1 //===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the llvm::sys::RWMutex class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SYSTEM_RWMUTEX_H
15 #define LLVM_SYSTEM_RWMUTEX_H
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/Threading.h"
25 /// @brief Platform agnostic RWMutex class.
28 /// @name Constructors
32 /// Initializes the lock but doesn't acquire it.
33 /// @brief Default Constructor.
34 explicit RWMutexImpl();
36 /// Releases and removes the lock
45 /// Attempts to unconditionally acquire the lock in reader mode. If the
46 /// lock is held by a writer, this method will wait until it can acquire
48 /// @returns false if any kind of error occurs, true otherwise.
49 /// @brief Unconditionally acquire the lock in reader mode.
50 bool reader_acquire();
52 /// Attempts to release the lock in reader mode.
53 /// @returns false if any kind of error occurs, true otherwise.
54 /// @brief Unconditionally release the lock in reader mode.
55 bool reader_release();
57 /// Attempts to unconditionally acquire the lock in reader mode. If the
58 /// lock is held by any readers, this method will wait until it can
60 /// @returns false if any kind of error occurs, true otherwise.
61 /// @brief Unconditionally acquire the lock in writer mode.
62 bool writer_acquire();
64 /// Attempts to release the lock in writer mode.
65 /// @returns false if any kind of error occurs, true otherwise.
66 /// @brief Unconditionally release the lock in write mode.
67 bool writer_release();
70 /// @name Platform Dependent Data
73 void* data_; ///< We don't know what the data will be
76 /// @name Do Not Implement
79 RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
80 void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
84 /// SmartMutex - An R/W mutex with a compile time constant parameter that
85 /// indicates whether this mutex should become a no-op when we're not
86 /// running in multithreaded mode.
87 template<bool mt_only>
88 class SmartRWMutex : public RWMutexImpl {
89 unsigned readers, writers;
91 explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
93 bool reader_acquire() {
94 if (!mt_only || llvm_is_multithreaded())
95 return RWMutexImpl::reader_acquire();
97 // Single-threaded debugging code. This would be racy in multithreaded
98 // mode, but provides not sanity checks in single threaded mode.
103 bool reader_release() {
104 if (!mt_only || llvm_is_multithreaded())
105 return RWMutexImpl::reader_release();
107 // Single-threaded debugging code. This would be racy in multithreaded
108 // mode, but provides not sanity checks in single threaded mode.
109 assert(readers > 0 && "Reader lock not acquired before release!");
114 bool writer_acquire() {
115 if (!mt_only || llvm_is_multithreaded())
116 return RWMutexImpl::writer_acquire();
118 // Single-threaded debugging code. This would be racy in multithreaded
119 // mode, but provides not sanity checks in single threaded mode.
120 assert(writers == 0 && "Writer lock already acquired!");
125 bool writer_release() {
126 if (!mt_only || llvm_is_multithreaded())
127 return RWMutexImpl::writer_release();
129 // Single-threaded debugging code. This would be racy in multithreaded
130 // mode, but provides not sanity checks in single threaded mode.
131 assert(writers == 1 && "Writer lock not acquired before release!");
137 SmartRWMutex(const SmartRWMutex<mt_only> & original);
138 void operator=(const SmartRWMutex<mt_only> &);
140 typedef SmartRWMutex<false> RWMutex;
142 /// ScopedReader - RAII acquisition of a reader lock
143 template<bool mt_only>
144 struct SmartScopedReader {
145 SmartRWMutex<mt_only>& mutex;
147 explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
148 mutex.reader_acquire();
151 ~SmartScopedReader() {
152 mutex.reader_release();
155 typedef SmartScopedReader<false> ScopedReader;
157 /// ScopedWriter - RAII acquisition of a writer lock
158 template<bool mt_only>
159 struct SmartScopedWriter {
160 SmartRWMutex<mt_only>& mutex;
162 explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
163 mutex.writer_acquire();
166 ~SmartScopedWriter() {
167 mutex.writer_release();
170 typedef SmartScopedWriter<false> ScopedWriter;