X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSystem%2FMutex.h;h=d2c457dbc91c6d14203295740c6442196d5433a6;hb=ed1c0ffe0b2287deaee7cba7506c93aa34c6d4b7;hp=8b5078d16d6cc5f4f4ae1d49d7e42d6a4292d226;hpb=6d2352249af8853c8307a7cf679017b32d27958c;p=oota-llvm.git diff --git a/include/llvm/System/Mutex.h b/include/llvm/System/Mutex.h index 8b5078d16d6..d2c457dbc91 100644 --- a/include/llvm/System/Mutex.h +++ b/include/llvm/System/Mutex.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Reid Spencer and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,12 +14,15 @@ #ifndef LLVM_SYSTEM_MUTEX_H #define LLVM_SYSTEM_MUTEX_H +#include "llvm/System/Threading.h" +#include + namespace llvm { namespace sys { /// @brief Platform agnostic Mutex class. - class Mutex + class MutexImpl { /// @name Constructors /// @{ @@ -30,11 +33,11 @@ namespace llvm /// also more likely to deadlock (same thread can't acquire more than /// once). /// @brief Default Constructor. - Mutex ( bool recursive = true ); + explicit MutexImpl(bool recursive = true); /// Releases and removes the lock /// @brief Destructor - ~Mutex ( void ); + ~MutexImpl(); /// @} /// @name Methods @@ -49,10 +52,10 @@ namespace llvm /// 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. + /// lock. /// @returns false if any kind of error occurs, true otherwise. /// @brief Unconditionally release the lock. - bool release(void); + bool release(); /// Attempts to acquire the lock without blocking. If the lock is not /// available, this function returns false quickly (without blocking). If @@ -61,7 +64,7 @@ namespace llvm /// available, true otherwise. /// @brief Try to acquire the lock. bool tryacquire(); - + //@} /// @name Platform Dependent Data /// @{ @@ -71,11 +74,76 @@ namespace llvm /// @} /// @name Do Not Implement /// @{ - private: - Mutex(const Mutex & original); - void operator=(const Mutex &); + private: + MutexImpl(const MutexImpl & original); + void operator=(const MutexImpl &); /// @} }; + + + /// 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 + class SmartMutex : public MutexImpl { + unsigned acquired; + bool recursive; + public: + explicit SmartMutex(bool rec = true) : + MutexImpl(rec), acquired(0), recursive(rec) { } + + bool acquire() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::acquire(); + + // 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 release() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::release(); + + // 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 tryacquire() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::tryacquire(); + return true; + } + + private: + SmartMutex(const SmartMutex & original); + void operator=(const SmartMutex &); + }; + + /// Mutex - A standard, always enforced mutex. + typedef SmartMutex Mutex; + + template + class SmartScopedLock { + SmartMutex* mtx; + + public: + SmartScopedLock(SmartMutex* m) : mtx(m) { + mtx->acquire(); + } + + ~SmartScopedLock() { + mtx->release(); + } + }; + + typedef SmartScopedLock ScopedLock; } }