#define LLVM_SYSTEM_RWMUTEX_H
#include "llvm/System/Threading.h"
+#include <cassert>
namespace llvm
{
/// @name Platform Dependent Data
/// @{
private:
-#ifdef ENABLE_THREADS
void* data_; ///< We don't know what the data will be
-#endif
/// @}
/// @name Do Not Implement
/// indicates whether this mutex should become a no-op when we're not
/// running in multithreaded mode.
template<bool mt_only>
- class SmartRWMutex : RWMutexImpl {
+ class SmartRWMutex : public RWMutexImpl {
+ unsigned readers, writers;
public:
- explicit SmartRWMutex() : RWMutexImpl() { }
+ explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
bool reader_acquire() {
- if (!mt_only && llvm_is_multithreaded())
+ 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;
}
/// ScopedReader - RAII acquisition of a reader lock
template<bool mt_only>
struct SmartScopedReader {
- SmartRWMutex<mt_only>* mutex;
+ SmartRWMutex<mt_only>& mutex;
- explicit SmartScopedReader(SmartRWMutex<mt_only>* m) {
- mutex = m;
- mutex->reader_acquire();
+ explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.reader_acquire();
}
~SmartScopedReader() {
- mutex->reader_release();
+ mutex.reader_release();
}
};
typedef SmartScopedReader<false> ScopedReader;
/// ScopedWriter - RAII acquisition of a writer lock
template<bool mt_only>
struct SmartScopedWriter {
- SmartRWMutex<mt_only>* mutex;
+ SmartRWMutex<mt_only>& mutex;
- explicit SmartScopedWriter(SmartRWMutex<mt_only>* m) {
- mutex = m;
- mutex->writer_acquire();
+ explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
+ mutex.writer_acquire();
}
~SmartScopedWriter() {
- mutex->writer_release();
+ mutex.writer_release();
}
};
typedef SmartScopedWriter<false> ScopedWriter;