Canonicalize header guards into a common format.
[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       void* data_; ///< We don't know what the data will be
74
75     /// @}
76     /// @name Do Not Implement
77     /// @{
78     private:
79       RWMutexImpl(const RWMutexImpl & original) LLVM_DELETED_FUNCTION;
80       void operator=(const RWMutexImpl &) LLVM_DELETED_FUNCTION;
81     /// @}
82     };
83
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;
90     public:
91       explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
92
93       bool reader_acquire() {
94         if (!mt_only || llvm_is_multithreaded())
95           return RWMutexImpl::reader_acquire();
96
97         // Single-threaded debugging code.  This would be racy in multithreaded
98         // mode, but provides not sanity checks in single threaded mode.
99         ++readers;
100         return true;
101       }
102
103       bool reader_release() {
104         if (!mt_only || llvm_is_multithreaded())
105           return RWMutexImpl::reader_release();
106
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!");
110         --readers;
111         return true;
112       }
113
114       bool writer_acquire() {
115         if (!mt_only || llvm_is_multithreaded())
116           return RWMutexImpl::writer_acquire();
117
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!");
121         ++writers;
122         return true;
123       }
124
125       bool writer_release() {
126         if (!mt_only || llvm_is_multithreaded())
127           return RWMutexImpl::writer_release();
128
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!");
132         --writers;
133         return true;
134       }
135
136     private:
137       SmartRWMutex(const SmartRWMutex<mt_only> & original);
138       void operator=(const SmartRWMutex<mt_only> &);
139     };
140     typedef SmartRWMutex<false> RWMutex;
141
142     /// ScopedReader - RAII acquisition of a reader lock
143     template<bool mt_only>
144     struct SmartScopedReader {
145       SmartRWMutex<mt_only>& mutex;
146
147       explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
148         mutex.reader_acquire();
149       }
150
151       ~SmartScopedReader() {
152         mutex.reader_release();
153       }
154     };
155     typedef SmartScopedReader<false> ScopedReader;
156
157     /// ScopedWriter - RAII acquisition of a writer lock
158     template<bool mt_only>
159     struct SmartScopedWriter {
160       SmartRWMutex<mt_only>& mutex;
161
162       explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
163         mutex.writer_acquire();
164       }
165
166       ~SmartScopedWriter() {
167         mutex.writer_release();
168       }
169     };
170     typedef SmartScopedWriter<false> ScopedWriter;
171   }
172 }
173
174 #endif