2009-06-16 22:19:28 +02:00
|
|
|
//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file declares the llvm::sys::RWMutex class.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-06-16 22:26:04 +02:00
|
|
|
#ifndef LLVM_SYSTEM_RWMUTEX_H
|
|
|
|
#define LLVM_SYSTEM_RWMUTEX_H
|
2009-06-16 22:19:28 +02:00
|
|
|
|
2010-11-29 19:16:10 +01:00
|
|
|
#include "llvm/Support/Threading.h"
|
2009-06-20 02:27:21 +02:00
|
|
|
#include <cassert>
|
2009-06-18 20:26:15 +02:00
|
|
|
|
2009-06-16 22:19:28 +02:00
|
|
|
namespace llvm
|
|
|
|
{
|
|
|
|
namespace sys
|
|
|
|
{
|
2009-06-18 20:26:15 +02:00
|
|
|
/// @brief Platform agnostic RWMutex class.
|
|
|
|
class RWMutexImpl
|
2009-06-16 22:19:28 +02:00
|
|
|
{
|
|
|
|
/// @name Constructors
|
|
|
|
/// @{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Initializes the lock but doesn't acquire it.
|
|
|
|
/// @brief Default Constructor.
|
2009-06-18 20:26:15 +02:00
|
|
|
explicit RWMutexImpl();
|
2009-06-16 22:19:28 +02:00
|
|
|
|
|
|
|
/// Releases and removes the lock
|
|
|
|
/// @brief Destructor
|
2009-06-18 20:26:15 +02:00
|
|
|
~RWMutexImpl();
|
2009-06-16 22:19:28 +02:00
|
|
|
|
|
|
|
/// @}
|
|
|
|
/// @name Methods
|
|
|
|
/// @{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// Attempts to unconditionally acquire the lock in reader mode. If the
|
|
|
|
/// lock is held by a writer, this method will wait until it can acquire
|
2010-11-29 19:16:10 +01:00
|
|
|
/// the lock.
|
2009-06-16 22:19:28 +02:00
|
|
|
/// @returns false if any kind of error occurs, true otherwise.
|
|
|
|
/// @brief Unconditionally acquire the lock in reader mode.
|
|
|
|
bool reader_acquire();
|
|
|
|
|
|
|
|
/// Attempts to release the lock in reader mode.
|
|
|
|
/// @returns false if any kind of error occurs, true otherwise.
|
|
|
|
/// @brief Unconditionally release the lock in reader mode.
|
|
|
|
bool reader_release();
|
|
|
|
|
|
|
|
/// Attempts to unconditionally acquire the lock in reader mode. If the
|
|
|
|
/// lock is held by any readers, this method will wait until it can
|
2010-11-29 19:16:10 +01:00
|
|
|
/// acquire the lock.
|
2009-06-16 22:19:28 +02:00
|
|
|
/// @returns false if any kind of error occurs, true otherwise.
|
|
|
|
/// @brief Unconditionally acquire the lock in writer mode.
|
|
|
|
bool writer_acquire();
|
|
|
|
|
|
|
|
/// Attempts to release the lock in writer mode.
|
|
|
|
/// @returns false if any kind of error occurs, true otherwise.
|
|
|
|
/// @brief Unconditionally release the lock in write mode.
|
|
|
|
bool writer_release();
|
|
|
|
|
|
|
|
//@}
|
|
|
|
/// @name Platform Dependent Data
|
|
|
|
/// @{
|
|
|
|
private:
|
|
|
|
void* data_; ///< We don't know what the data will be
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
/// @name Do Not Implement
|
|
|
|
/// @{
|
|
|
|
private:
|
2009-06-18 20:26:15 +02:00
|
|
|
RWMutexImpl(const RWMutexImpl & original);
|
|
|
|
void operator=(const RWMutexImpl &);
|
2009-06-16 22:19:28 +02:00
|
|
|
/// @}
|
|
|
|
};
|
2010-11-29 19:16:10 +01:00
|
|
|
|
|
|
|
/// SmartMutex - An R/W mutex with a compile time constant parameter that
|
2009-06-18 20:26:15 +02:00
|
|
|
/// indicates whether this mutex should become a no-op when we're not
|
|
|
|
/// running in multithreaded mode.
|
|
|
|
template<bool mt_only>
|
2009-06-19 02:48:22 +02:00
|
|
|
class SmartRWMutex : public RWMutexImpl {
|
2009-06-20 02:27:21 +02:00
|
|
|
unsigned readers, writers;
|
2009-06-18 20:26:15 +02:00
|
|
|
public:
|
2009-06-20 02:27:21 +02:00
|
|
|
explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { }
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
bool reader_acquire() {
|
2009-06-19 02:48:22 +02:00
|
|
|
if (!mt_only || llvm_is_multithreaded())
|
2009-06-18 20:26:15 +02:00
|
|
|
return RWMutexImpl::reader_acquire();
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-20 02:27:21 +02:00
|
|
|
// Single-threaded debugging code. This would be racy in multithreaded
|
|
|
|
// mode, but provides not sanity checks in single threaded mode.
|
|
|
|
++readers;
|
2009-06-18 20:26:15 +02:00
|
|
|
return true;
|
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
bool reader_release() {
|
|
|
|
if (!mt_only || llvm_is_multithreaded())
|
|
|
|
return RWMutexImpl::reader_release();
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-20 02:27:21 +02:00
|
|
|
// 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;
|
2009-06-18 20:26:15 +02:00
|
|
|
return true;
|
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
bool writer_acquire() {
|
|
|
|
if (!mt_only || llvm_is_multithreaded())
|
|
|
|
return RWMutexImpl::writer_acquire();
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-20 02:27:21 +02:00
|
|
|
// 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;
|
2009-06-18 20:26:15 +02:00
|
|
|
return true;
|
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
bool writer_release() {
|
|
|
|
if (!mt_only || llvm_is_multithreaded())
|
|
|
|
return RWMutexImpl::writer_release();
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-20 02:27:21 +02:00
|
|
|
// 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;
|
2009-06-18 20:26:15 +02:00
|
|
|
return true;
|
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
private:
|
|
|
|
SmartRWMutex(const SmartRWMutex<mt_only> & original);
|
|
|
|
void operator=(const SmartRWMutex<mt_only> &);
|
|
|
|
};
|
|
|
|
typedef SmartRWMutex<false> RWMutex;
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 01:49:06 +02:00
|
|
|
/// ScopedReader - RAII acquisition of a reader lock
|
2009-06-18 20:26:15 +02:00
|
|
|
template<bool mt_only>
|
|
|
|
struct SmartScopedReader {
|
2009-07-07 20:33:04 +02:00
|
|
|
SmartRWMutex<mt_only>& mutex;
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-07-07 20:33:04 +02:00
|
|
|
explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
|
|
|
|
mutex.reader_acquire();
|
2009-06-18 00:23:31 +02:00
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
~SmartScopedReader() {
|
2009-07-07 20:33:04 +02:00
|
|
|
mutex.reader_release();
|
2009-06-18 00:23:31 +02:00
|
|
|
}
|
|
|
|
};
|
2009-06-18 20:26:15 +02:00
|
|
|
typedef SmartScopedReader<false> ScopedReader;
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-17 22:34:43 +02:00
|
|
|
/// ScopedWriter - RAII acquisition of a writer lock
|
2009-06-18 20:26:15 +02:00
|
|
|
template<bool mt_only>
|
|
|
|
struct SmartScopedWriter {
|
2009-07-07 20:33:04 +02:00
|
|
|
SmartRWMutex<mt_only>& mutex;
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-07-07 20:33:04 +02:00
|
|
|
explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
|
|
|
|
mutex.writer_acquire();
|
2009-06-17 22:34:43 +02:00
|
|
|
}
|
2010-11-29 19:16:10 +01:00
|
|
|
|
2009-06-18 20:26:15 +02:00
|
|
|
~SmartScopedWriter() {
|
2009-07-07 20:33:04 +02:00
|
|
|
mutex.writer_release();
|
2009-06-17 22:34:43 +02:00
|
|
|
}
|
|
|
|
};
|
2009-06-18 20:26:15 +02:00
|
|
|
typedef SmartScopedWriter<false> ScopedWriter;
|
2009-06-16 22:19:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|