]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Support/RWMutex.h
MFV r357163:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Support / RWMutex.h
1 //===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the llvm::sys::RWMutex class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_SUPPORT_RWMUTEX_H
14 #define LLVM_SUPPORT_RWMUTEX_H
15
16 #include "llvm/Config/llvm-config.h"
17 #include "llvm/Support/Threading.h"
18 #include <cassert>
19
20 namespace llvm {
21 namespace sys {
22
23     /// Platform agnostic RWMutex class.
24     class RWMutexImpl
25     {
26     /// @name Constructors
27     /// @{
28     public:
29
30       /// Initializes the lock but doesn't acquire it.
31       /// Default Constructor.
32       explicit RWMutexImpl();
33
34     /// @}
35     /// @name Do Not Implement
36     /// @{
37       RWMutexImpl(const RWMutexImpl & original) = delete;
38       RWMutexImpl &operator=(const RWMutexImpl &) = delete;
39     /// @}
40
41       /// Releases and removes the lock
42       /// Destructor
43       ~RWMutexImpl();
44
45     /// @}
46     /// @name Methods
47     /// @{
48     public:
49
50       /// Attempts to unconditionally acquire the lock in reader mode. If the
51       /// lock is held by a writer, this method will wait until it can acquire
52       /// the lock.
53       /// @returns false if any kind of error occurs, true otherwise.
54       /// Unconditionally acquire the lock in reader mode.
55       bool reader_acquire();
56
57       /// Attempts to release the lock in reader mode.
58       /// @returns false if any kind of error occurs, true otherwise.
59       /// Unconditionally release the lock in reader mode.
60       bool reader_release();
61
62       /// Attempts to unconditionally acquire the lock in reader mode. If the
63       /// lock is held by any readers, this method will wait until it can
64       /// acquire the lock.
65       /// @returns false if any kind of error occurs, true otherwise.
66       /// Unconditionally acquire the lock in writer mode.
67       bool writer_acquire();
68
69       /// Attempts to release the lock in writer mode.
70       /// @returns false if any kind of error occurs, true otherwise.
71       /// Unconditionally release the lock in write mode.
72       bool writer_release();
73
74     //@}
75     /// @name Platform Dependent Data
76     /// @{
77     private:
78 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
79       void* data_ = nullptr; ///< We don't know what the data will be
80 #endif
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 {
88       RWMutexImpl impl;
89       unsigned readers = 0;
90       unsigned writers = 0;
91
92     public:
93       explicit SmartRWMutex() = default;
94       SmartRWMutex(const SmartRWMutex<mt_only> & original) = delete;
95       SmartRWMutex<mt_only> &operator=(const SmartRWMutex<mt_only> &) = delete;
96
97       bool lock_shared() {
98         if (!mt_only || llvm_is_multithreaded())
99           return impl.reader_acquire();
100
101         // Single-threaded debugging code.  This would be racy in multithreaded
102         // mode, but provides not sanity checks in single threaded mode.
103         ++readers;
104         return true;
105       }
106
107       bool unlock_shared() {
108         if (!mt_only || llvm_is_multithreaded())
109           return impl.reader_release();
110
111         // Single-threaded debugging code.  This would be racy in multithreaded
112         // mode, but provides not sanity checks in single threaded mode.
113         assert(readers > 0 && "Reader lock not acquired before release!");
114         --readers;
115         return true;
116       }
117
118       bool lock() {
119         if (!mt_only || llvm_is_multithreaded())
120           return impl.writer_acquire();
121
122         // Single-threaded debugging code.  This would be racy in multithreaded
123         // mode, but provides not sanity checks in single threaded mode.
124         assert(writers == 0 && "Writer lock already acquired!");
125         ++writers;
126         return true;
127       }
128
129       bool unlock() {
130         if (!mt_only || llvm_is_multithreaded())
131           return impl.writer_release();
132
133         // Single-threaded debugging code.  This would be racy in multithreaded
134         // mode, but provides not sanity checks in single threaded mode.
135         assert(writers == 1 && "Writer lock not acquired before release!");
136         --writers;
137         return true;
138       }
139     };
140
141     typedef SmartRWMutex<false> RWMutex;
142
143     /// ScopedReader - RAII acquisition of a reader lock
144     template<bool mt_only>
145     struct SmartScopedReader {
146       SmartRWMutex<mt_only>& mutex;
147
148       explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
149         mutex.lock_shared();
150       }
151
152       ~SmartScopedReader() {
153         mutex.unlock_shared();
154       }
155     };
156
157     typedef SmartScopedReader<false> ScopedReader;
158
159     /// ScopedWriter - RAII acquisition of a writer lock
160     template<bool mt_only>
161     struct SmartScopedWriter {
162       SmartRWMutex<mt_only>& mutex;
163
164       explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
165         mutex.lock();
166       }
167
168       ~SmartScopedWriter() {
169         mutex.unlock();
170       }
171     };
172
173     typedef SmartScopedWriter<false> ScopedWriter;
174
175 } // end namespace sys
176 } // end namespace llvm
177
178 #endif // LLVM_SUPPORT_RWMUTEX_H