diff options
Diffstat (limited to 'clang-r353983/include/llvm/Support/RWMutex.h')
| -rw-r--r-- | clang-r353983/include/llvm/Support/RWMutex.h | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/Support/RWMutex.h b/clang-r353983/include/llvm/Support/RWMutex.h new file mode 100644 index 00000000..9cd57cbd --- /dev/null +++ b/clang-r353983/include/llvm/Support/RWMutex.h @@ -0,0 +1,178 @@ +//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the llvm::sys::RWMutex class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_RWMUTEX_H +#define LLVM_SUPPORT_RWMUTEX_H + +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/Threading.h" +#include <cassert> + +namespace llvm { +namespace sys { + + /// Platform agnostic RWMutex class. + class RWMutexImpl + { + /// @name Constructors + /// @{ + public: + + /// Initializes the lock but doesn't acquire it. + /// Default Constructor. + explicit RWMutexImpl(); + + /// @} + /// @name Do Not Implement + /// @{ + RWMutexImpl(const RWMutexImpl & original) = delete; + RWMutexImpl &operator=(const RWMutexImpl &) = delete; + /// @} + + /// Releases and removes the lock + /// Destructor + ~RWMutexImpl(); + + /// @} + /// @name Methods + /// @{ + public: + + /// Attempts to unconditionally acquire the lock in reader mode. If the + /// lock is held by a writer, this method will wait until it can acquire + /// the lock. + /// @returns false if any kind of error occurs, true otherwise. + /// Unconditionally acquire the lock in reader mode. + bool reader_acquire(); + + /// Attempts to release the lock in reader mode. + /// @returns false if any kind of error occurs, true otherwise. + /// Unconditionally release the lock in reader mode. + bool reader_release(); + + /// Attempts to unconditionally acquire the lock in reader mode. If the + /// lock is held by any readers, this method will wait until it can + /// acquire the lock. + /// @returns false if any kind of error occurs, true otherwise. + /// Unconditionally acquire the lock in writer mode. + bool writer_acquire(); + + /// Attempts to release the lock in writer mode. + /// @returns false if any kind of error occurs, true otherwise. + /// Unconditionally release the lock in write mode. + bool writer_release(); + + //@} + /// @name Platform Dependent Data + /// @{ + private: +#if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0 + void* data_ = nullptr; ///< We don't know what the data will be +#endif + }; + + /// SmartMutex - An R/W mutex with a compile time constant parameter that + /// indicates whether this mutex should become a no-op when we're not + /// running in multithreaded mode. + template<bool mt_only> + class SmartRWMutex { + RWMutexImpl impl; + unsigned readers = 0; + unsigned writers = 0; + + public: + explicit SmartRWMutex() = default; + SmartRWMutex(const SmartRWMutex<mt_only> & original) = delete; + SmartRWMutex<mt_only> &operator=(const SmartRWMutex<mt_only> &) = delete; + + bool lock_shared() { + if (!mt_only || llvm_is_multithreaded()) + return impl.reader_acquire(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + ++readers; + return true; + } + + bool unlock_shared() { + if (!mt_only || llvm_is_multithreaded()) + return impl.reader_release(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(readers > 0 && "Reader lock not acquired before release!"); + --readers; + return true; + } + + bool lock() { + if (!mt_only || llvm_is_multithreaded()) + return impl.writer_acquire(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(writers == 0 && "Writer lock already acquired!"); + ++writers; + return true; + } + + bool unlock() { + if (!mt_only || llvm_is_multithreaded()) + return impl.writer_release(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(writers == 1 && "Writer lock not acquired before release!"); + --writers; + return true; + } + }; + + typedef SmartRWMutex<false> RWMutex; + + /// ScopedReader - RAII acquisition of a reader lock + template<bool mt_only> + struct SmartScopedReader { + SmartRWMutex<mt_only>& mutex; + + explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) { + mutex.lock_shared(); + } + + ~SmartScopedReader() { + mutex.unlock_shared(); + } + }; + + typedef SmartScopedReader<false> ScopedReader; + + /// ScopedWriter - RAII acquisition of a writer lock + template<bool mt_only> + struct SmartScopedWriter { + SmartRWMutex<mt_only>& mutex; + + explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) { + mutex.lock(); + } + + ~SmartScopedWriter() { + mutex.unlock(); + } + }; + + typedef SmartScopedWriter<false> ScopedWriter; + +} // end namespace sys +} // end namespace llvm + +#endif // LLVM_SUPPORT_RWMUTEX_H |
