#ifndef LLVM_SYSTEM_RWMUTEX_H
#define LLVM_SYSTEM_RWMUTEX_H
+#include "llvm/System/Threading.h"
+#include <cassert>
+
namespace llvm
{
namespace sys
{
- /// @brief Platform agnostic Mutex class.
- class RWMutex
+ /// @brief Platform agnostic RWMutex class.
+ class RWMutexImpl
{
/// @name Constructors
/// @{
/// 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
/// @name Platform Dependent Data
/// @{
private:
-#ifdef ENABLE_THREADS
void* data_; ///< We don't know what the data will be
-#endif
/// @}
/// @name Do Not Implement
/// @{
private:
- RWMutex(const RWMutex & original);
- void operator=(const RWMutex &);
+ RWMutexImpl(const RWMutexImpl & original);
+ void operator=(const RWMutexImpl &);
/// @}
};
+ /// 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<bool mt_only>
+ class SmartRWMutex : public RWMutexImpl {
+ unsigned readers, writers;
+ public:
+ explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
+
+ bool reader_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ ++readers;
+ return true;
+ }
+
+ bool reader_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::reader_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(readers > 0 && "Reader lock not acquired before release!");
+ --readers;
+ return true;
+ }
+
+ bool writer_acquire() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_acquire();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 0 && "Writer lock already acquired!");
+ ++writers;
+ return true;
+ }
+
+ bool writer_release() {
+ if (!mt_only || llvm_is_multithreaded())
+ return RWMutexImpl::writer_release();
+
+ // Single-threaded debugging code. This would be racy in multithreaded
+ // mode, but provides not sanity checks in single threaded mode.
+ assert(writers == 1 && "Writer lock not acquired before release!");
+ --writers;
+ return true;
+ }
+
+ private:
+ SmartRWMutex(const SmartRWMutex<mt_only> & original);
+ void operator=(const SmartRWMutex<mt_only> &);
+ };
+ typedef SmartRWMutex<false> RWMutex;
+
/// ScopedReader - RAII acquisition of a reader lock
- struct ScopedReader {
- RWMutex* mutex;
+ template<bool mt_only>
+ struct SmartScopedReader {
+ SmartRWMutex<mt_only>& mutex;
- explicit ScopedReader(RWMutex* m) {
- mutex = m;
- mutex->reader_acquire();
+ explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.reader_acquire();
}
- ~ScopedReader() {
- mutex->reader_release();
+ ~SmartScopedReader() {
+ mutex.reader_release();
}
};
+ typedef SmartScopedReader<false> ScopedReader;
/// ScopedWriter - RAII acquisition of a writer lock
- struct ScopedWriter {
- RWMutex* mutex;
+ template<bool mt_only>
+ struct SmartScopedWriter {
+ SmartRWMutex<mt_only>& mutex;
- explicit ScopedWriter(RWMutex* m) {
- mutex = m;
- mutex->writer_acquire();
+ explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.writer_acquire();
}
- ~ScopedWriter() {
- mutex->writer_release();
+ ~SmartScopedWriter() {
+ mutex.writer_release();
}
};
+ typedef SmartScopedWriter<false> ScopedWriter;
}
}