Mutex.h revision cc40f077b018e62e2e6f5dc279e3be84779569ce
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file declares the llvm::sys::Mutex class. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_SYSTEM_MUTEX_H 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_SYSTEM_MUTEX_H 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/System/Threading.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cassert> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namespace sys 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @brief Platform agnostic Mutex class. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class MutexImpl 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @name Constructors 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @{ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Initializes the lock but doesn't acquire it. if \p recursive is set 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// to false, the lock will not be recursive which makes it cheaper but 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// also more likely to deadlock (same thread can't acquire more than 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// once). 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @brief Default Constructor. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MutexImpl(bool recursive = true); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Releases and removes the lock 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @brief Destructor 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MutexImpl(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @name Methods 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @{ 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Attempts to unconditionally acquire the lock. If the lock is held by 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// another thread, this method will wait until it can acquire the lock. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @returns false if any kind of error occurs, true otherwise. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// @brief Unconditionally acquire the lock. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 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