diff --git a/include/llvm/System/RWMutex.h b/include/llvm/System/RWMutex.h index 0a3932e6560..6a254b873a5 100644 --- a/include/llvm/System/RWMutex.h +++ b/include/llvm/System/RWMutex.h @@ -14,12 +14,14 @@ #ifndef LLVM_SYSTEM_RWMUTEX_H #define LLVM_SYSTEM_RWMUTEX_H +#include "llvm/System/Threading.h" + namespace llvm { namespace sys { - /// @brief Platform agnostic Mutex class. - class RWMutex + /// @brief Platform agnostic RWMutex class. + class RWMutexImpl { /// @name Constructors /// @{ @@ -27,11 +29,11 @@ namespace llvm /// Initializes the lock but doesn't acquire it. /// @brief Default Constructor. - explicit RWMutex(); + explicit RWMutexImpl(); /// Releases and removes the lock /// @brief Destructor - ~RWMutex(); + ~RWMutexImpl(); /// @} /// @name Methods @@ -74,38 +76,80 @@ namespace llvm /// @name Do Not Implement /// @{ private: - RWMutex(const RWMutex & original); - void operator=(const RWMutex &); + RWMutexImpl(const RWMutexImpl & original); + void operator=(const RWMutexImpl &); /// @} }; - /// ScopedReader - RAII acquisition of a reader lock - struct ScopedReader { - RWMutex* mutex; + /// SmartMutex - An R/W 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 SmartRWMutex : RWMutexImpl { + public: + explicit SmartRWMutex() : RWMutexImpl() { } - explicit ScopedReader(RWMutex* m) { + bool reader_acquire() { + if (!mt_only && llvm_is_multithreaded()) + return RWMutexImpl::reader_acquire(); + return true; + } + + bool reader_release() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::reader_release(); + return true; + } + + bool writer_acquire() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::writer_acquire(); + return true; + } + + bool writer_release() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::writer_release(); + return true; + } + + private: + SmartRWMutex(const SmartRWMutex & original); + void operator=(const SmartRWMutex &); + }; + typedef SmartRWMutex RWMutex; + + /// ScopedReader - RAII acquisition of a reader lock + template + struct SmartScopedReader { + SmartRWMutex* mutex; + + explicit SmartScopedReader(SmartRWMutex* m) { mutex = m; mutex->reader_acquire(); } - ~ScopedReader() { + ~SmartScopedReader() { mutex->reader_release(); } }; + typedef SmartScopedReader ScopedReader; /// ScopedWriter - RAII acquisition of a writer lock - struct ScopedWriter { - RWMutex* mutex; + template + struct SmartScopedWriter { + SmartRWMutex* mutex; - explicit ScopedWriter(RWMutex* m) { + explicit SmartScopedWriter(SmartRWMutex* m) { mutex = m; mutex->writer_acquire(); } - ~ScopedWriter() { + ~SmartScopedWriter() { mutex->writer_release(); } }; + typedef SmartScopedWriter ScopedWriter; } } diff --git a/lib/System/RWMutex.cpp b/lib/System/RWMutex.cpp index 2b6cf6c2148..cf1aea03ddf 100644 --- a/lib/System/RWMutex.cpp +++ b/lib/System/RWMutex.cpp @@ -23,12 +23,12 @@ // Define all methods as no-ops if threading is explicitly disabled namespace llvm { using namespace sys; -RWMutex::RWMutex() { } -RWMutex::~RWMutex() { } -bool RWMutex::reader_acquire() { return true; } -bool RWMutex::reader_release() { return true; } -bool RWMutex::writer_acquire() { return true; } -bool RWMutex::writer_release() { return true; } +RWMutexImpl::RWMutexImpl() { } +RWMutexImpl::~RWMutexImpl() { } +bool RWMutexImpl::reader_acquire() { return true; } +bool RWMutexImpl::reader_release() { return true; } +bool RWMutexImpl::writer_acquire() { return true; } +bool RWMutexImpl::writer_release() { return true; } } #else @@ -56,7 +56,7 @@ using namespace sys; static const bool pthread_enabled = true; // Construct a RWMutex using pthread calls -RWMutex::RWMutex() +RWMutexImpl::RWMutexImpl() : data_(0) { if (pthread_enabled) @@ -89,7 +89,7 @@ RWMutex::RWMutex() } // Destruct a RWMutex -RWMutex::~RWMutex() +RWMutexImpl::~RWMutexImpl() { if (pthread_enabled) { @@ -101,7 +101,7 @@ RWMutex::~RWMutex() } bool -RWMutex::reader_acquire() +RWMutexImpl::reader_acquire() { if (pthread_enabled) { @@ -115,7 +115,7 @@ RWMutex::reader_acquire() } bool -RWMutex::reader_release() +RWMutexImpl::reader_release() { if (pthread_enabled) { @@ -129,7 +129,7 @@ RWMutex::reader_release() } bool -RWMutex::writer_acquire() +RWMutexImpl::writer_acquire() { if (pthread_enabled) { @@ -143,7 +143,7 @@ RWMutex::writer_acquire() } bool -RWMutex::writer_release() +RWMutexImpl::writer_release() { if (pthread_enabled) { diff --git a/lib/System/Unix/RWMutex.inc b/lib/System/Unix/RWMutex.inc index 4487d7f83da..e83d41ef4cf 100644 --- a/lib/System/Unix/RWMutex.inc +++ b/lib/System/Unix/RWMutex.inc @@ -20,23 +20,23 @@ namespace llvm { using namespace sys; -RWMutex::RWMutex() { } +RWMutexImpl::RWMutexImpl() { } -RWMutex::~RWMutex() { } +RWMutexImpl::~RWMutexImpl() { } -bool RWMutex::reader_acquire() { +bool RWMutexImpl::reader_acquire() { return true; } -bool RWMutex::reader_release() { +bool RWMutexImpl::reader_release() { return true; } -bool RWMutex::writer_acquire() { +bool RWMutexImpl::writer_acquire() { return true; } -bool RWMutex::writer_release() { +bool RWMutexImpl::writer_release() { return true; } diff --git a/lib/System/Win32/RWMutex.inc b/lib/System/Win32/RWMutex.inc index 7fc4b33b1e9..e2692269e3a 100644 --- a/lib/System/Win32/RWMutex.inc +++ b/lib/System/Win32/RWMutex.inc @@ -24,32 +24,32 @@ namespace llvm { using namespace sys; -RWMutex::RWMutex() { +RWMutexImpl::RWMutexImpl() { data_ = calloc(1, sizeof(CRITICAL_SECTION)); InitializeCriticalSection(static_cast(data_)); } -RWMutex::~RWMutex() { +RWMutexImpl::~RWMutexImpl() { DeleteCriticalSection(static_cast(data_)); free(data_); } -bool RWMutex::reader_acquire() { +bool RWMutexImpl::reader_acquire() { EnterCriticalSection(static_cast(data_)); return true; } -bool RWMutex::reader_release() { +bool RWMutexImpl::reader_release() { LeaveCriticalSection(static_cast(data_)); return true; } -bool RWMutex::writer_acquire() { +bool RWMutexImpl::writer_acquire() { EnterCriticalSection(static_cast(data_)); return true; } -bool RWMutex::writer_release() { +bool RWMutexImpl::writer_release() { LeaveCriticalSection(static_cast(data_)); return true; }