Mutex.h revision a9d1f2c559ef4b2549e29288fe6944e68913ba0f
1//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file declares the llvm::sys::Mutex class. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SYSTEM_MUTEX_H 15#define LLVM_SYSTEM_MUTEX_H 16 17#include "llvm/System/Threading.h" 18#include <cassert> 19 20namespace llvm 21{ 22 namespace sys 23 { 24 /// @brief Platform agnostic Mutex class. 25 class MutexImpl 26 { 27 /// @name Constructors 28 /// @{ 29 public: 30 31 /// Initializes the lock but doesn't acquire it. if \p recursive is set 32 /// to false, the lock will not be recursive which makes it cheaper but 33 /// also more likely to deadlock (same thread can't acquire more than 34 /// once). 35 /// @brief Default Constructor. 36 explicit MutexImpl(bool recursive = true); 37 38 /// Releases and removes the lock 39 /// @brief Destructor 40 ~MutexImpl(); 41 42 /// @} 43 /// @name Methods 44 /// @{ 45 public: 46 47 /// Attempts to unconditionally acquire the lock. If the lock is held by 48 /// another thread, this method will wait until it can acquire the lock. 49 /// @returns false if any kind of error occurs, true otherwise. 50 /// @brief Unconditionally acquire the lock. 51 bool acquire(); 52 53 /// Attempts to release the lock. If the lock is held by the current 54 /// thread, the lock is released allowing other threads to acquire the 55 /// lock. 56 /// @returns false if any kind of error occurs, true otherwise. 57 /// @brief Unconditionally release the lock. 58 bool release(); 59 60 /// Attempts to acquire the lock without blocking. If the lock is not 61 /// available, this function returns false quickly (without blocking). If 62 /// the lock is available, it is acquired. 63 /// @returns false if any kind of error occurs or the lock is not 64 /// available, true otherwise. 65 /// @brief Try to acquire the lock. 66 bool tryacquire(); 67 68 //@} 69 /// @name Platform Dependent Data 70 /// @{ 71 private: 72 void* data_; ///< We don't know what the data will be 73 74 /// @} 75 /// @name Do Not Implement 76 /// @{ 77 private: 78 MutexImpl(const MutexImpl & original); 79 void operator=(const MutexImpl &); 80 /// @} 81 }; 82 83 84 /// SmartMutex - A mutex with a compile time constant parameter that 85 /// indicates whether this mutex should become a no-op when we're not 86 /// running in multithreaded mode. 87 template<bool mt_only> 88 class SmartMutex : public MutexImpl { 89 unsigned acquired; 90 bool recursive; 91 public: 92 explicit SmartMutex(bool rec = true) : 93 MutexImpl(rec), acquired(0), recursive(rec) { } 94 95 bool acquire() { 96 if (!mt_only || llvm_is_multithreaded()) 97 return MutexImpl::acquire(); 98 99 // Single-threaded debugging code. This would be racy in multithreaded 100 // mode, but provides not sanity checks in single threaded mode. 101 assert((recursive || acquired == 0) && "Lock already acquired!!"); 102 ++acquired; 103 return true; 104 } 105 106 bool release() { 107 if (!mt_only || llvm_is_multithreaded()) 108 return MutexImpl::release(); 109 110 // Single-threaded debugging code. This would be racy in multithreaded 111 // mode, but provides not sanity checks in single threaded mode. 112 assert(((recursive && acquired) || (acquired == 1)) && 113 "Lock not acquired before release!"); 114 --acquired; 115 return true; 116 } 117 118 bool tryacquire() { 119 if (!mt_only || llvm_is_multithreaded()) 120 return MutexImpl::tryacquire(); 121 return true; 122 } 123 124 private: 125 SmartMutex(const SmartMutex<mt_only> & original); 126 void operator=(const SmartMutex<mt_only> &); 127 }; 128 129 /// Mutex - A standard, always enforced mutex. 130 typedef SmartMutex<false> Mutex; 131 132 template<bool mt_only> 133 class SmartScopedLock { 134 SmartMutex<mt_only>& mtx; 135 136 public: 137 SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { 138 mtx.acquire(); 139 } 140 141 ~SmartScopedLock() { 142 mtx.release(); 143 } 144 }; 145 146 typedef SmartScopedLock<false> ScopedLock; 147 } 148} 149 150#endif 151