Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:33

0001 //===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares the llvm::sys::RWMutex class.
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 /// Platform agnostic RWMutex class.
0031 class RWMutexImpl {
0032   /// @name Constructors
0033   /// @{
0034 public:
0035   /// Initializes the lock but doesn't acquire it.
0036   /// Default Constructor.
0037   explicit RWMutexImpl();
0038 
0039   /// @}
0040   /// @name Do Not Implement
0041   /// @{
0042   RWMutexImpl(const RWMutexImpl &original) = delete;
0043   RWMutexImpl &operator=(const RWMutexImpl &) = delete;
0044   /// @}
0045 
0046   /// Releases and removes the lock
0047   /// Destructor
0048   ~RWMutexImpl();
0049 
0050   /// @}
0051   /// @name Methods
0052   /// @{
0053 public:
0054   /// Attempts to unconditionally acquire the lock in reader mode. If the
0055   /// lock is held by a writer, this method will wait until it can acquire
0056   /// the lock.
0057   /// @returns false if any kind of error occurs, true otherwise.
0058   /// Unconditionally acquire the lock in reader mode.
0059   bool lock_shared();
0060 
0061   /// Attempts to release the lock in reader mode.
0062   /// @returns false if any kind of error occurs, true otherwise.
0063   /// Unconditionally release the lock in reader mode.
0064   bool unlock_shared();
0065 
0066   /// Attempts to acquire the lock in reader mode. Returns immediately.
0067   /// @returns true on successful lock acquisition, false otherwise.
0068   bool try_lock_shared();
0069 
0070   /// Attempts to unconditionally acquire the lock in reader mode. If the
0071   /// lock is held by any readers, this method will wait until it can
0072   /// acquire the lock.
0073   /// @returns false if any kind of error occurs, true otherwise.
0074   /// Unconditionally acquire the lock in writer mode.
0075   bool lock();
0076 
0077   /// Attempts to release the lock in writer mode.
0078   /// @returns false if any kind of error occurs, true otherwise.
0079   /// Unconditionally release the lock in write mode.
0080   bool unlock();
0081 
0082   /// Attempts to acquire the lock in writer mode. Returns immediately.
0083   /// @returns true on successful lock acquisition, false otherwise.
0084   bool try_lock();
0085 
0086   //@}
0087   /// @name Platform Dependent Data
0088   /// @{
0089 private:
0090 #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
0091   void *data_ = nullptr; ///< We don't know what the data will be
0092 #endif
0093 };
0094 #endif
0095 
0096 /// SmartMutex - An R/W mutex with a compile time constant parameter that
0097 /// indicates whether this mutex should become a no-op when we're not
0098 /// running in multithreaded mode.
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     // Single-threaded debugging code.  This would be racy in multithreaded
0116     // mode, but provides not basic checks in single threaded mode.
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     // Single-threaded debugging code.  This would be racy in multithreaded
0128     // mode, but provides not basic checks in single threaded mode.
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     // Single-threaded debugging code.  This would be racy in multithreaded
0143     // mode, but provides not basic checks in single threaded mode.
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     // Single-threaded debugging code.  This would be racy in multithreaded
0156     // mode, but provides not basic checks in single threaded mode.
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 /// ScopedReader - RAII acquisition of a reader lock
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 /// ScopedWriter - RAII acquisition of a writer lock
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 } // end namespace sys
0202 } // end namespace llvm
0203 
0204 #endif // LLVM_SUPPORT_RWMUTEX_H