Fixed/added namespace ending comments using clang-tidy. NFC
[oota-llvm.git] / include / llvm / Support / RWMutex.h
1 //===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the llvm::sys::RWMutex class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SUPPORT_RWMUTEX_H
15 #define LLVM_SUPPORT_RWMUTEX_H
16
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/Threading.h"
19 #include <cassert>
20
21 namespace llvm
22 {
23   namespace sys
24   {
25     /// @brief Platform agnostic RWMutex class.
26     class RWMutexImpl
27     {
28     /// @name Constructors
29     /// @{
30     public:
31
32       /// Initializes the lock but doesn't acquire it.
33       /// @brief Default Constructor.
34       explicit RWMutexImpl();
35
36       /// Releases and removes the lock
37       /// @brief Destructor
38       ~RWMutexImpl();
39
40     /// @}
41     /// @name Methods
42     /// @{
43     public:
44
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
47       /// the lock.
48       /// @returns false if any kind of error occurs, true otherwise.
49       /// @brief Unconditionally acquire the lock in reader mode.
50       bool reader_acquire();
51
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();
56
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
59       /// acquire the lock.
60       /// @returns false if any kind of error occurs, true otherwise.
61       /// @brief Unconditionally acquire the lock in writer mode.
62       bool writer_acquire();
63
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();
68
69     //@}
70     /// @name Platform Dependent Data
71     /// @{
72     private:
73 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
74       void* data_; ///< We don't know what the data will be
75 #endif
76
77     /// @}
78     /// @name Do Not Implement
79     /// @{
80     private:
81       RWMutexImpl(const RWMutexImpl & original) = delete;
82       void operator=(const RWMutexImpl &) = delete;
83     /// @}
84     };
85
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>
90     class SmartRWMutex {
91       RWMutexImpl impl;
92       unsigned readers, writers;
93     public:
94       explicit SmartRWMutex() : impl(), readers(0), writers(0) { }
95
96       bool lock_shared() {
97         if (!mt_only || llvm_is_multithreaded())
98           return impl.reader_acquire();
99
100         // Single-threaded debugging code.  This would be racy in multithreaded
101         // mode, but provides not sanity checks in single threaded mode.
102         ++readers;
103         return true;
104       }
105
106       bool unlock_shared() {
107         if (!mt_only || llvm_is_multithreaded())
108           return impl.reader_release();
109
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!");
113         --readers;
114         return true;
115       }
116
117       bool lock() {
118         if (!mt_only || llvm_is_multithreaded())
119           return impl.writer_acquire();
120
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!");
124         ++writers;
125         return true;
126       }
127
128       bool unlock() {
129         if (!mt_only || llvm_is_multithreaded())
130           return impl.writer_release();
131
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!");
135         --writers;
136         return true;
137       }
138
139     private:
140       SmartRWMutex(const SmartRWMutex<mt_only> & original);
141       void operator=(const SmartRWMutex<mt_only> &);
142     };
143     typedef SmartRWMutex<false> RWMutex;
144
145     /// ScopedReader - RAII acquisition of a reader lock
146     template<bool mt_only>
147     struct SmartScopedReader {
148       SmartRWMutex<mt_only>& mutex;
149
150       explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
151         mutex.lock_shared();
152       }
153
154       ~SmartScopedReader() {
155         mutex.unlock_shared();
156       }
157     };
158     typedef SmartScopedReader<false> ScopedReader;
159
160     /// ScopedWriter - RAII acquisition of a writer lock
161     template<bool mt_only>
162     struct SmartScopedWriter {
163       SmartRWMutex<mt_only>& mutex;
164
165       explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
166         mutex.lock();
167       }
168
169       ~SmartScopedWriter() {
170         mutex.unlock();
171       }
172     };
173     typedef SmartScopedWriter<false> ScopedWriter;
174   } // namespace sys
175 } // namespace llvm
176
177 #endif