• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SYSTEM_RWMUTEX_H
15 #define LLVM_SYSTEM_RWMUTEX_H
16 
17 #include "llvm/Support/Threading.h"
18 #include <cassert>
19 
20 namespace llvm
21 {
22   namespace sys
23   {
24     /// @brief Platform agnostic RWMutex class.
25     class RWMutexImpl
26     {
27     /// @name Constructors
28     /// @{
29     public:
30 
31       /// Initializes the lock but doesn't acquire it.
32       /// @brief Default Constructor.
33       explicit RWMutexImpl();
34 
35       /// Releases and removes the lock
36       /// @brief Destructor
37       ~RWMutexImpl();
38 
39     /// @}
40     /// @name Methods
41     /// @{
42     public:
43 
44       /// Attempts to unconditionally acquire the lock in reader mode. If the
45       /// lock is held by a writer, this method will wait until it can acquire
46       /// the lock.
47       /// @returns false if any kind of error occurs, true otherwise.
48       /// @brief Unconditionally acquire the lock in reader mode.
49       bool reader_acquire();
50 
51       /// Attempts to release the lock in reader mode.
52       /// @returns false if any kind of error occurs, true otherwise.
53       /// @brief Unconditionally release the lock in reader mode.
54       bool reader_release();
55 
56       /// Attempts to unconditionally acquire the lock in reader mode. If the
57       /// lock is held by any readers, this method will wait until it can
58       /// acquire the lock.
59       /// @returns false if any kind of error occurs, true otherwise.
60       /// @brief Unconditionally acquire the lock in writer mode.
61       bool writer_acquire();
62 
63       /// Attempts to release the lock in writer mode.
64       /// @returns false if any kind of error occurs, true otherwise.
65       /// @brief Unconditionally release the lock in write mode.
66       bool writer_release();
67 
68     //@}
69     /// @name Platform Dependent Data
70     /// @{
71     private:
72       void* data_; ///< We don't know what the data will be
73 
74     /// @}
75     /// @name Do Not Implement
76     /// @{
77     private:
78       RWMutexImpl(const RWMutexImpl & original);
79       void operator=(const RWMutexImpl &);
80     /// @}
81     };
82 
83     /// SmartMutex - An R/W mutex with a compile time constant parameter that
84     /// indicates whether this mutex should become a no-op when we're not
85     /// running in multithreaded mode.
86     template<bool mt_only>
87     class SmartRWMutex : public RWMutexImpl {
88       unsigned readers, writers;
89     public:
SmartRWMutex()90       explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
91 
reader_acquire()92       bool reader_acquire() {
93         if (!mt_only || llvm_is_multithreaded())
94           return RWMutexImpl::reader_acquire();
95 
96         // Single-threaded debugging code.  This would be racy in multithreaded
97         // mode, but provides not sanity checks in single threaded mode.
98         ++readers;
99         return true;
100       }
101 
reader_release()102       bool reader_release() {
103         if (!mt_only || llvm_is_multithreaded())
104           return RWMutexImpl::reader_release();
105 
106         // Single-threaded debugging code.  This would be racy in multithreaded
107         // mode, but provides not sanity checks in single threaded mode.
108         assert(readers > 0 && "Reader lock not acquired before release!");
109         --readers;
110         return true;
111       }
112 
writer_acquire()113       bool writer_acquire() {
114         if (!mt_only || llvm_is_multithreaded())
115           return RWMutexImpl::writer_acquire();
116 
117         // Single-threaded debugging code.  This would be racy in multithreaded
118         // mode, but provides not sanity checks in single threaded mode.
119         assert(writers == 0 && "Writer lock already acquired!");
120         ++writers;
121         return true;
122       }
123 
writer_release()124       bool writer_release() {
125         if (!mt_only || llvm_is_multithreaded())
126           return RWMutexImpl::writer_release();
127 
128         // Single-threaded debugging code.  This would be racy in multithreaded
129         // mode, but provides not sanity checks in single threaded mode.
130         assert(writers == 1 && "Writer lock not acquired before release!");
131         --writers;
132         return true;
133       }
134 
135     private:
136       SmartRWMutex(const SmartRWMutex<mt_only> & original);
137       void operator=(const SmartRWMutex<mt_only> &);
138     };
139     typedef SmartRWMutex<false> RWMutex;
140 
141     /// ScopedReader - RAII acquisition of a reader lock
142     template<bool mt_only>
143     struct SmartScopedReader {
144       SmartRWMutex<mt_only>& mutex;
145 
SmartScopedReaderSmartScopedReader146       explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
147         mutex.reader_acquire();
148       }
149 
~SmartScopedReaderSmartScopedReader150       ~SmartScopedReader() {
151         mutex.reader_release();
152       }
153     };
154     typedef SmartScopedReader<false> ScopedReader;
155 
156     /// ScopedWriter - RAII acquisition of a writer lock
157     template<bool mt_only>
158     struct SmartScopedWriter {
159       SmartRWMutex<mt_only>& mutex;
160 
SmartScopedWriterSmartScopedWriter161       explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
162         mutex.writer_acquire();
163       }
164 
~SmartScopedWriterSmartScopedWriter165       ~SmartScopedWriter() {
166         mutex.writer_release();
167       }
168     };
169     typedef SmartScopedWriter<false> ScopedWriter;
170   }
171 }
172 
173 #endif
174