Mutex.h revision 1f6efa3996dd1929fbc129203ce5009b620e6969
1b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===// 2b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// 3b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// The LLVM Compiler Infrastructure 4b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 7b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// 8b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===----------------------------------------------------------------------===// 9b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// 10b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// This file declares the llvm::sys::Mutex class. 11b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer// 12b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer//===----------------------------------------------------------------------===// 13b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 14b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#ifndef LLVM_SYSTEM_MUTEX_H 15b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#define LLVM_SYSTEM_MUTEX_H 16b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 171f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Threading.h" 18cc40f077b018e62e2e6f5dc279e3be84779569ceOwen Anderson#include <cassert> 19b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson 20b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencernamespace llvm 21b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer{ 22b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer namespace sys 23b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer { 24b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Platform agnostic Mutex class. 25b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson class MutexImpl 26b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer { 27b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @name Constructors 28b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @{ 29b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer public: 30b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 31b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// Initializes the lock but doesn't acquire it. if \p recursive is set 32b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// to false, the lock will not be recursive which makes it cheaper but 33b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// also more likely to deadlock (same thread can't acquire more than 34b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// once). 35b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Default Constructor. 36b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson explicit MutexImpl(bool recursive = true); 37b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 38b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// Releases and removes the lock 39b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Destructor 40b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson ~MutexImpl(); 41b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 42b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @} 43b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @name Methods 44b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @{ 45b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer public: 46b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 47b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// Attempts to unconditionally acquire the lock. If the lock is held by 48b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// another thread, this method will wait until it can acquire the lock. 49b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @returns false if any kind of error occurs, true otherwise. 50b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Unconditionally acquire the lock. 51b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer bool acquire(); 52b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 53b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// Attempts to release the lock. If the lock is held by the current 54b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// thread, the lock is released allowing other threads to acquire the 559eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen /// lock. 56b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @returns false if any kind of error occurs, true otherwise. 57b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Unconditionally release the lock. 58e98fc32b0d80663aff215e328bcd297b3141b565Dan Gohman bool release(); 59b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 60b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// Attempts to acquire the lock without blocking. If the lock is not 61b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// available, this function returns false quickly (without blocking). If 62b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// the lock is available, it is acquired. 63b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @returns false if any kind of error occurs or the lock is not 64b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// available, true otherwise. 65b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @brief Try to acquire the lock. 66b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer bool tryacquire(); 679eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen 68b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer //@} 69b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @name Platform Dependent Data 70b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @{ 71b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer private: 726d2352249af8853c8307a7cf679017b32d27958cJeff Cohen void* data_; ///< We don't know what the data will be 73b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 74b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @} 75b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @name Do Not Implement 76b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @{ 779eb59ec548b861d6ede05b4e6dc22aabf645e665Jeff Cohen private: 78b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson MutexImpl(const MutexImpl & original); 79b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson void operator=(const MutexImpl &); 80b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer /// @} 81b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer }; 821f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 831f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 841f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer /// SmartMutex - A mutex with a compile time constant parameter that 85b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson /// indicates whether this mutex should become a no-op when we're not 86b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson /// running in multithreaded mode. 87b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson template<bool mt_only> 88f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson class SmartMutex : public MutexImpl { 89cc40f077b018e62e2e6f5dc279e3be84779569ceOwen Anderson unsigned acquired; 90cc40f077b018e62e2e6f5dc279e3be84779569ceOwen Anderson bool recursive; 91b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson public: 92cc40f077b018e62e2e6f5dc279e3be84779569ceOwen Anderson explicit SmartMutex(bool rec = true) : 93cc40f077b018e62e2e6f5dc279e3be84779569ceOwen Anderson MutexImpl(rec), acquired(0), recursive(rec) { } 941f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 95b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson bool acquire() { 96740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands if (!mt_only || llvm_is_multithreaded()) { 97f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson return MutexImpl::acquire(); 98740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands } else { 99740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // Single-threaded debugging code. This would be racy in 100740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // multithreaded mode, but provides not sanity checks in single 101740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // threaded mode. 102740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands assert((recursive || acquired == 0) && "Lock already acquired!!"); 103740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands ++acquired; 104740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands return true; 105740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands } 106b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson } 107b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson 108b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson bool release() { 109740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands if (!mt_only || llvm_is_multithreaded()) { 110f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson return MutexImpl::release(); 111740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands } else { 112740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // Single-threaded debugging code. This would be racy in 113740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // multithreaded mode, but provides not sanity checks in single 114740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands // threaded mode. 115740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands assert(((recursive && acquired) || (acquired == 1)) && 116740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands "Lock not acquired before release!"); 117740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands --acquired; 118740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands return true; 119740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands } 120b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson } 121b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson 122b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson bool tryacquire() { 123f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson if (!mt_only || llvm_is_multithreaded()) 124f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson return MutexImpl::tryacquire(); 125740eb5323e449ae4b00a3f657bffaceadcbe2624Duncan Sands else return true; 126b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson } 1271f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 128b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson private: 129f0eeb9b7f580a3e92c0a740893b7956801eafd52Owen Anderson SmartMutex(const SmartMutex<mt_only> & original); 130b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson void operator=(const SmartMutex<mt_only> &); 131b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson }; 1321f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 133b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson /// Mutex - A standard, always enforced mutex. 134b849a4dd4bee9ad17e295691087ce09e8d77d685Owen Anderson typedef SmartMutex<false> Mutex; 1351f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 1363c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson template<bool mt_only> 1373c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson class SmartScopedLock { 138a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson SmartMutex<mt_only>& mtx; 1391f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 1403c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson public: 141a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { 142a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson mtx.acquire(); 1433c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson } 1441f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 1453c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson ~SmartScopedLock() { 146a9d1f2c559ef4b2549e29288fe6944e68913ba0fOwen Anderson mtx.release(); 1473c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson } 1483c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson }; 1491f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer 1503c8031df6d555ab6dc6b629273fd8244b801e4d6Owen Anderson typedef SmartScopedLock<false> ScopedLock; 151b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer } 152b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer} 153b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer 154b2164e5cb5086f0595e96fdbb5ffc614dea9c441Reid Spencer#endif 155