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/Config/llvm-config.h"
18 #include "llvm/Support/Threading.h"
19 #include <cassert>
20 
Java_org_rocksdb_ColumnFamilyHandle_getName(JNIEnv * env,jobject,jlong jhandle)21 namespace llvm {
22 namespace sys {
23 
24     /// 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       /// Default Constructor.
33       explicit RWMutexImpl();
34 
35     /// @}
36     /// @name Do Not Implement
37     /// @{
38       RWMutexImpl(const RWMutexImpl & original) = delete;
39       RWMutexImpl &operator=(const RWMutexImpl &) = delete;
40     /// @}
41 
42       /// Releases and removes the lock
43       /// Destructor
44       ~RWMutexImpl();
45 
46     /// @}
47     /// @name Methods
48     /// @{
49     public:
50 
51       /// Attempts to unconditionally acquire the lock in reader mode. If the
52       /// lock is held by a writer, this method will wait until it can acquire
53       /// the lock.
54       /// @returns false if any kind of error occurs, true otherwise.
55       /// Unconditionally acquire the lock in reader mode.
56       bool reader_acquire();
57 
58       /// Attempts to release the lock in reader mode.
59       /// @returns false if any kind of error occurs, true otherwise.
60       /// Unconditionally release the lock in reader mode.
61       bool reader_release();
62 
63       /// Attempts to unconditionally acquire the lock in reader mode. If the
64       /// lock is held by any readers, this method will wait until it can
65       /// acquire the lock.
66       /// @returns false if any kind of error occurs, true otherwise.
67       /// Unconditionally acquire the lock in writer mode.
68       bool writer_acquire();
69 
70       /// Attempts to release the lock in writer mode.
71       /// @returns false if any kind of error occurs, true otherwise.
72       /// Unconditionally release the lock in write mode.
73       bool writer_release();
74 
75     //@}
76     /// @name Platform Dependent Data
77     /// @{
78     private:
79 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
80       void* data_ = nullptr; ///< We don't know what the data will be
81 #endif
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 {
89       RWMutexImpl impl;
90       unsigned readers = 0;
91       unsigned writers = 0;
92 
93     public:
94       explicit SmartRWMutex() = default;
95       SmartRWMutex(const SmartRWMutex<mt_only> & original) = delete;
96       SmartRWMutex<mt_only> &operator=(const SmartRWMutex<mt_only> &) = delete;
97 
98       bool lock_shared() {
99         if (!mt_only || llvm_is_multithreaded())
100           return impl.reader_acquire();
101 
102         // Single-threaded debugging code.  This would be racy in multithreaded
103         // mode, but provides not sanity checks in single threaded mode.
104         ++readers;
105         return true;
106       }
107 
108       bool unlock_shared() {
109         if (!mt_only || llvm_is_multithreaded())
110           return impl.reader_release();
111 
112         // Single-threaded debugging code.  This would be racy in multithreaded
113         // mode, but provides not sanity checks in single threaded mode.
114         assert(readers > 0 && "Reader lock not acquired before release!");
115         --readers;
116         return true;
117       }
118 
119       bool lock() {
120         if (!mt_only || llvm_is_multithreaded())
121           return impl.writer_acquire();
122 
123         // Single-threaded debugging code.  This would be racy in multithreaded
124         // mode, but provides not sanity checks in single threaded mode.
125         assert(writers == 0 && "Writer lock already acquired!");
126         ++writers;
127         return true;
128       }
129 
130       bool unlock() {
131         if (!mt_only || llvm_is_multithreaded())
132           return impl.writer_release();
133 
134         // Single-threaded debugging code.  This would be racy in multithreaded
135         // mode, but provides not sanity checks in single threaded mode.
136         assert(writers == 1 && "Writer lock not acquired before release!");
137         --writers;
138         return true;
139       }
140     };
141 
142     typedef SmartRWMutex<false> RWMutex;
143 
144     /// ScopedReader - RAII acquisition of a reader lock
145     template<bool mt_only>
146     struct SmartScopedReader {
147       SmartRWMutex<mt_only>& mutex;
148 
149       explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
150         mutex.lock_shared();
151       }
152 
153       ~SmartScopedReader() {
154         mutex.unlock_shared();
155       }
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 
174     typedef SmartScopedWriter<false> ScopedWriter;
175 
176 } // end namespace sys
177 } // end namespace llvm
178 
179 #endif // LLVM_SUPPORT_RWMUTEX_H
180