LLVM 19.0.0git
RWMutex.h
Go to the documentation of this file.
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"
18#include <cassert>
19#include <mutex>
20#include <shared_mutex>
21
22#if defined(__APPLE__)
23#define LLVM_USE_RW_MUTEX_IMPL
24#endif
25
26namespace llvm {
27namespace sys {
28
29#if defined(LLVM_USE_RW_MUTEX_IMPL)
30/// Platform agnostic RWMutex class.
31class RWMutexImpl {
32 /// @name Constructors
33 /// @{
34public:
35 /// Initializes the lock but doesn't acquire it.
36 /// Default Constructor.
37 explicit RWMutexImpl();
38
39 /// @}
40 /// @name Do Not Implement
41 /// @{
42 RWMutexImpl(const RWMutexImpl &original) = delete;
43 RWMutexImpl &operator=(const RWMutexImpl &) = delete;
44 /// @}
45
46 /// Releases and removes the lock
47 /// Destructor
48 ~RWMutexImpl();
49
50 /// @}
51 /// @name Methods
52 /// @{
53public:
54 /// Attempts to unconditionally acquire the lock in reader mode. If the
55 /// lock is held by a writer, this method will wait until it can acquire
56 /// the lock.
57 /// @returns false if any kind of error occurs, true otherwise.
58 /// Unconditionally acquire the lock in reader mode.
59 bool lock_shared();
60
61 /// Attempts to release the lock in reader mode.
62 /// @returns false if any kind of error occurs, true otherwise.
63 /// Unconditionally release the lock in reader mode.
64 bool unlock_shared();
65
66 /// Attempts to unconditionally acquire the lock in reader mode. If the
67 /// lock is held by any readers, this method will wait until it can
68 /// acquire the lock.
69 /// @returns false if any kind of error occurs, true otherwise.
70 /// Unconditionally acquire the lock in writer mode.
71 bool lock();
72
73 /// Attempts to release the lock in writer mode.
74 /// @returns false if any kind of error occurs, true otherwise.
75 /// Unconditionally release the lock in write mode.
76 bool unlock();
77
78 //@}
79 /// @name Platform Dependent Data
80 /// @{
81private:
82#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
83 void *data_ = nullptr; ///< We don't know what the data will be
84#endif
85};
86#endif
87
88/// SmartMutex - An R/W mutex with a compile time constant parameter that
89/// indicates whether this mutex should become a no-op when we're not
90/// running in multithreaded mode.
91template <bool mt_only> class SmartRWMutex {
92#if !defined(LLVM_USE_RW_MUTEX_IMPL)
93 std::shared_mutex impl;
94#else
95 RWMutexImpl impl;
96#endif
97 unsigned readers = 0;
98 unsigned writers = 0;
99
100public:
101 bool lock_shared() {
102 if (!mt_only || llvm_is_multithreaded()) {
103 impl.lock_shared();
104 return true;
105 }
106
107 // Single-threaded debugging code. This would be racy in multithreaded
108 // mode, but provides not basic checks in single threaded mode.
109 ++readers;
110 return true;
111 }
112
114 if (!mt_only || llvm_is_multithreaded()) {
115 impl.unlock_shared();
116 return true;
117 }
118
119 // Single-threaded debugging code. This would be racy in multithreaded
120 // mode, but provides not basic checks in single threaded mode.
121 assert(readers > 0 && "Reader lock not acquired before release!");
122 --readers;
123 return true;
124 }
125
126 bool lock() {
127 if (!mt_only || llvm_is_multithreaded()) {
128 impl.lock();
129 return true;
130 }
131
132 // Single-threaded debugging code. This would be racy in multithreaded
133 // mode, but provides not basic checks in single threaded mode.
134 assert(writers == 0 && "Writer lock already acquired!");
135 ++writers;
136 return true;
137 }
138
139 bool unlock() {
140 if (!mt_only || llvm_is_multithreaded()) {
141 impl.unlock();
142 return true;
143 }
144
145 // Single-threaded debugging code. This would be racy in multithreaded
146 // mode, but provides not basic checks in single threaded mode.
147 assert(writers == 1 && "Writer lock not acquired before release!");
148 --writers;
149 return true;
150 }
151};
152
154
155/// ScopedReader - RAII acquisition of a reader lock
156#if !defined(LLVM_USE_RW_MUTEX_IMPL)
157template <bool mt_only>
158using SmartScopedReader = const std::shared_lock<SmartRWMutex<mt_only>>;
159#else
160template <bool mt_only> struct SmartScopedReader {
162
163 explicit SmartScopedReader(SmartRWMutex<mt_only> &m) : mutex(m) {
164 mutex.lock_shared();
165 }
166
167 ~SmartScopedReader() { mutex.unlock_shared(); }
168};
169#endif
171
172/// ScopedWriter - RAII acquisition of a writer lock
173#if !defined(LLVM_USE_RW_MUTEX_IMPL)
174template <bool mt_only>
175using SmartScopedWriter = std::lock_guard<SmartRWMutex<mt_only>>;
176#else
177template <bool mt_only> struct SmartScopedWriter {
179
180 explicit SmartScopedWriter(SmartRWMutex<mt_only> &m) : mutex(m) {
181 mutex.lock();
182 }
183
184 ~SmartScopedWriter() { mutex.unlock(); }
185};
186#endif
188
189} // end namespace sys
190} // end namespace llvm
191
192#endif // LLVM_SUPPORT_RWMUTEX_H
place backedge safepoints impl
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SmartMutex - An R/W mutex with a compile time constant parameter that indicates whether this mutex sh...
Definition: RWMutex.h:91
SmartScopedReader< false > ScopedReader
Definition: RWMutex.h:170
SmartScopedWriter< false > ScopedWriter
Definition: RWMutex.h:187
const std::shared_lock< SmartRWMutex< mt_only > > SmartScopedReader
ScopedReader - RAII acquisition of a reader lock.
Definition: RWMutex.h:158
std::lock_guard< SmartRWMutex< mt_only > > SmartScopedWriter
ScopedWriter - RAII acquisition of a writer lock.
Definition: RWMutex.h:175
SmartRWMutex< false > RWMutex
Definition: RWMutex.h:153
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
constexpr bool llvm_is_multithreaded()
Returns true if LLVM is compiled with support for multi-threading, and false otherwise.
Definition: Threading.h:53