File indexing completed on 2026-05-10 08:44:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_SUPPORT_RWMUTEX_H
0014 #define LLVM_SUPPORT_RWMUTEX_H
0015
0016 #include "llvm/Config/llvm-config.h"
0017 #include "llvm/Support/Threading.h"
0018 #include <cassert>
0019 #include <mutex>
0020 #include <shared_mutex>
0021
0022 #if defined(__APPLE__)
0023 #define LLVM_USE_RW_MUTEX_IMPL
0024 #endif
0025
0026 namespace llvm {
0027 namespace sys {
0028
0029 #if defined(LLVM_USE_RW_MUTEX_IMPL)
0030
0031 class RWMutexImpl {
0032
0033
0034 public:
0035
0036
0037 explicit RWMutexImpl();
0038
0039
0040
0041
0042 RWMutexImpl(const RWMutexImpl &original) = delete;
0043 RWMutexImpl &operator=(const RWMutexImpl &) = delete;
0044
0045
0046
0047
0048 ~RWMutexImpl();
0049
0050
0051
0052
0053 public:
0054
0055
0056
0057
0058
0059 bool lock_shared();
0060
0061
0062
0063
0064 bool unlock_shared();
0065
0066
0067
0068 bool try_lock_shared();
0069
0070
0071
0072
0073
0074
0075 bool lock();
0076
0077
0078
0079
0080 bool unlock();
0081
0082
0083
0084 bool try_lock();
0085
0086
0087
0088
0089 private:
0090 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
0091 void *data_ = nullptr;
0092 #endif
0093 };
0094 #endif
0095
0096
0097
0098
0099 template <bool mt_only> class SmartRWMutex {
0100 #if !defined(LLVM_USE_RW_MUTEX_IMPL)
0101 std::shared_mutex impl;
0102 #else
0103 RWMutexImpl impl;
0104 #endif
0105 unsigned readers = 0;
0106 unsigned writers = 0;
0107
0108 public:
0109 bool lock_shared() {
0110 if (!mt_only || llvm_is_multithreaded()) {
0111 impl.lock_shared();
0112 return true;
0113 }
0114
0115
0116
0117 ++readers;
0118 return true;
0119 }
0120
0121 bool unlock_shared() {
0122 if (!mt_only || llvm_is_multithreaded()) {
0123 impl.unlock_shared();
0124 return true;
0125 }
0126
0127
0128
0129 assert(readers > 0 && "Reader lock not acquired before release!");
0130 --readers;
0131 return true;
0132 }
0133
0134 bool try_lock_shared() { return impl.try_lock_shared(); }
0135
0136 bool lock() {
0137 if (!mt_only || llvm_is_multithreaded()) {
0138 impl.lock();
0139 return true;
0140 }
0141
0142
0143
0144 assert(writers == 0 && "Writer lock already acquired!");
0145 ++writers;
0146 return true;
0147 }
0148
0149 bool unlock() {
0150 if (!mt_only || llvm_is_multithreaded()) {
0151 impl.unlock();
0152 return true;
0153 }
0154
0155
0156
0157 assert(writers == 1 && "Writer lock not acquired before release!");
0158 --writers;
0159 return true;
0160 }
0161
0162 bool try_lock() { return impl.try_lock(); }
0163 };
0164
0165 typedef SmartRWMutex<false> RWMutex;
0166
0167
0168 #if !defined(LLVM_USE_RW_MUTEX_IMPL)
0169 template <bool mt_only>
0170 using SmartScopedReader = const std::shared_lock<SmartRWMutex<mt_only>>;
0171 #else
0172 template <bool mt_only> struct SmartScopedReader {
0173 SmartRWMutex<mt_only> &mutex;
0174
0175 explicit SmartScopedReader(SmartRWMutex<mt_only> &m) : mutex(m) {
0176 mutex.lock_shared();
0177 }
0178
0179 ~SmartScopedReader() { mutex.unlock_shared(); }
0180 };
0181 #endif
0182 typedef SmartScopedReader<false> ScopedReader;
0183
0184
0185 #if !defined(LLVM_USE_RW_MUTEX_IMPL)
0186 template <bool mt_only>
0187 using SmartScopedWriter = std::lock_guard<SmartRWMutex<mt_only>>;
0188 #else
0189 template <bool mt_only> struct SmartScopedWriter {
0190 SmartRWMutex<mt_only> &mutex;
0191
0192 explicit SmartScopedWriter(SmartRWMutex<mt_only> &m) : mutex(m) {
0193 mutex.lock();
0194 }
0195
0196 ~SmartScopedWriter() { mutex.unlock(); }
0197 };
0198 #endif
0199 typedef SmartScopedWriter<false> ScopedWriter;
0200
0201 }
0202 }
0203
0204 #endif