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_SUPPORT_RWMUTEX_H
15 #define LLVM_SUPPORT_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) = delete;
80 void operator=(const RWMutexImpl &) = delete;
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>
90 unsigned readers, writers;
92 explicit SmartRWMutex() : impl(), readers(0), writers(0) { }
95 if (!mt_only || llvm_is_multithreaded())
96 return impl.reader_acquire();
98 // Single-threaded debugging code. This would be racy in multithreaded
99 // mode, but provides not sanity checks in single threaded mode.
104 bool unlock_shared() {
105 if (!mt_only || llvm_is_multithreaded())
106 return impl.reader_release();
108 // Single-threaded debugging code. This would be racy in multithreaded
109 // mode, but provides not sanity checks in single threaded mode.
110 assert(readers > 0 && "Reader lock not acquired before release!");
116 if (!mt_only || llvm_is_multithreaded())
117 return impl.writer_acquire();
119 // Single-threaded debugging code. This would be racy in multithreaded
120 // mode, but provides not sanity checks in single threaded mode.
121 assert(writers == 0 && "Writer lock already acquired!");
127 if (!mt_only || llvm_is_multithreaded())
128 return impl.writer_release();
130 // Single-threaded debugging code. This would be racy in multithreaded
131 // mode, but provides not sanity checks in single threaded mode.
132 assert(writers == 1 && "Writer lock not acquired before release!");
138 SmartRWMutex(const SmartRWMutex<mt_only> & original);
139 void operator=(const SmartRWMutex<mt_only> &);
141 typedef SmartRWMutex<false> RWMutex;
143 /// ScopedReader - RAII acquisition of a reader lock
144 template<bool mt_only>
145 struct SmartScopedReader {
146 SmartRWMutex<mt_only>& mutex;
148 explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
152 ~SmartScopedReader() {
153 mutex.unlock_shared();
156 typedef SmartScopedReader<false> ScopedReader;
158 /// ScopedWriter - RAII acquisition of a writer lock
159 template<bool mt_only>
160 struct SmartScopedWriter {
161 SmartRWMutex<mt_only>& mutex;
163 explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
167 ~SmartScopedWriter() {
171 typedef SmartScopedWriter<false> ScopedWriter;