| //===- llvm/Support/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file declares the llvm::sys::Mutex class. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef LLVM_SUPPORT_MUTEX_H | 
 | #define LLVM_SUPPORT_MUTEX_H | 
 |  | 
 | #include "llvm/Support/Compiler.h" | 
 | #include "llvm/Support/Threading.h" | 
 | #include <cassert> | 
 |  | 
 | namespace llvm | 
 | { | 
 |   namespace sys | 
 |   { | 
 |     /// @brief Platform agnostic Mutex class. | 
 |     class MutexImpl | 
 |     { | 
 |     /// @name Constructors | 
 |     /// @{ | 
 |     public: | 
 |  | 
 |       /// Initializes the lock but doesn't acquire it. if \p recursive is set | 
 |       /// to false, the lock will not be recursive which makes it cheaper but | 
 |       /// also more likely to deadlock (same thread can't acquire more than | 
 |       /// once). | 
 |       /// @brief Default Constructor. | 
 |       explicit MutexImpl(bool recursive = true); | 
 |  | 
 |       /// Releases and removes the lock | 
 |       /// @brief Destructor | 
 |       ~MutexImpl(); | 
 |  | 
 |     /// @} | 
 |     /// @name Methods | 
 |     /// @{ | 
 |     public: | 
 |  | 
 |       /// Attempts to unconditionally acquire the lock. If the lock is held by | 
 |       /// another thread, this method will wait until it can acquire the lock. | 
 |       /// @returns false if any kind of error occurs, true otherwise. | 
 |       /// @brief Unconditionally acquire the lock. | 
 |       bool acquire(); | 
 |  | 
 |       /// Attempts to release the lock. If the lock is held by the current | 
 |       /// thread, the lock is released allowing other threads to acquire the | 
 |       /// lock. | 
 |       /// @returns false if any kind of error occurs, true otherwise. | 
 |       /// @brief Unconditionally release the lock. | 
 |       bool release(); | 
 |  | 
 |       /// Attempts to acquire the lock without blocking. If the lock is not | 
 |       /// available, this function returns false quickly (without blocking). If | 
 |       /// the lock is available, it is acquired. | 
 |       /// @returns false if any kind of error occurs or the lock is not | 
 |       /// available, true otherwise. | 
 |       /// @brief Try to acquire the lock. | 
 |       bool tryacquire(); | 
 |  | 
 |     //@} | 
 |     /// @name Platform Dependent Data | 
 |     /// @{ | 
 |     private: | 
 | #if defined(LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0 | 
 |       void* data_; ///< We don't know what the data will be | 
 | #endif | 
 |  | 
 |     /// @} | 
 |     /// @name Do Not Implement | 
 |     /// @{ | 
 |     private: | 
 |       MutexImpl(const MutexImpl &) = delete; | 
 |       void operator=(const MutexImpl &) = delete; | 
 |     /// @} | 
 |     }; | 
 |  | 
 |  | 
 |     /// SmartMutex - A 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 SmartMutex { | 
 |       MutexImpl impl; | 
 |       unsigned acquired; | 
 |       bool recursive; | 
 |     public: | 
 |       explicit SmartMutex(bool rec = true) : | 
 |         impl(rec), acquired(0), recursive(rec) { } | 
 |  | 
 |       bool lock() { | 
 |         if (!mt_only || llvm_is_multithreaded()) { | 
 |           return impl.acquire(); | 
 |         } else { | 
 |           // Single-threaded debugging code.  This would be racy in | 
 |           // multithreaded mode, but provides not sanity checks in single | 
 |           // threaded mode. | 
 |           assert((recursive || acquired == 0) && "Lock already acquired!!"); | 
 |           ++acquired; | 
 |           return true; | 
 |         } | 
 |       } | 
 |  | 
 |       bool unlock() { | 
 |         if (!mt_only || llvm_is_multithreaded()) { | 
 |           return impl.release(); | 
 |         } else { | 
 |           // Single-threaded debugging code.  This would be racy in | 
 |           // multithreaded mode, but provides not sanity checks in single | 
 |           // threaded mode. | 
 |           assert(((recursive && acquired) || (acquired == 1)) && | 
 |                  "Lock not acquired before release!"); | 
 |           --acquired; | 
 |           return true; | 
 |         } | 
 |       } | 
 |  | 
 |       bool try_lock() { | 
 |         if (!mt_only || llvm_is_multithreaded()) | 
 |           return impl.tryacquire(); | 
 |         else return true; | 
 |       } | 
 |  | 
 |       private: | 
 |         SmartMutex(const SmartMutex<mt_only> & original); | 
 |         void operator=(const SmartMutex<mt_only> &); | 
 |     }; | 
 |  | 
 |     /// Mutex - A standard, always enforced mutex. | 
 |     typedef SmartMutex<false> Mutex; | 
 |  | 
 |     template<bool mt_only> | 
 |     class SmartScopedLock  { | 
 |       SmartMutex<mt_only>& mtx; | 
 |  | 
 |     public: | 
 |       SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { | 
 |         mtx.lock(); | 
 |       } | 
 |  | 
 |       ~SmartScopedLock() { | 
 |         mtx.unlock(); | 
 |       } | 
 |     }; | 
 |  | 
 |     typedef SmartScopedLock<false> ScopedLock; | 
 |   } | 
 | } | 
 |  | 
 | #endif |