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 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
74 void* data_; ///< We don't know what the data will be
78 /// @name Do Not Implement
81 RWMutexImpl(const RWMutexImpl & original) = delete;
82 void operator=(const RWMutexImpl &) = delete;
86 /// SmartMutex - An R/W mutex with a compile time constant parameter that
87 /// indicates whether this mutex should become a no-op when we're not
88 /// running in multithreaded mode.
89 template<bool mt_only>
92 unsigned readers, writers;
94 explicit SmartRWMutex() : impl(), readers(0), writers(0) { }
97 if (!mt_only || llvm_is_multithreaded())
98 return impl.reader_acquire();
100 // Single-threaded debugging code. This would be racy in multithreaded
101 // mode, but provides not sanity checks in single threaded mode.
106 bool unlock_shared() {
107 if (!mt_only || llvm_is_multithreaded())
108 return impl.reader_release();
110 // Single-threaded debugging code. This would be racy in multithreaded
111 // mode, but provides not sanity checks in single threaded mode.
112 assert(readers > 0 && "Reader lock not acquired before release!");
118 if (!mt_only || llvm_is_multithreaded())
119 return impl.writer_acquire();
121 // Single-threaded debugging code. This would be racy in multithreaded
122 // mode, but provides not sanity checks in single threaded mode.
123 assert(writers == 0 && "Writer lock already acquired!");
129 if (!mt_only || llvm_is_multithreaded())
130 return impl.writer_release();
132 // Single-threaded debugging code. This would be racy in multithreaded
133 // mode, but provides not sanity checks in single threaded mode.
134 assert(writers == 1 && "Writer lock not acquired before release!");
140 SmartRWMutex(const SmartRWMutex<mt_only> & original);
141 void operator=(const SmartRWMutex<mt_only> &);
143 typedef SmartRWMutex<false> RWMutex;
145 /// ScopedReader - RAII acquisition of a reader lock
146 template<bool mt_only>
147 struct SmartScopedReader {
148 SmartRWMutex<mt_only>& mutex;
150 explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
154 ~SmartScopedReader() {
155 mutex.unlock_shared();
158 typedef SmartScopedReader<false> ScopedReader;
160 /// ScopedWriter - RAII acquisition of a writer lock
161 template<bool mt_only>
162 struct SmartScopedWriter {
163 SmartRWMutex<mt_only>& mutex;
165 explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
169 ~SmartScopedWriter() {
173 typedef SmartScopedWriter<false> ScopedWriter;