24 #ifndef PXR_BASE_TF_SPIN_RW_MUTEX_H 25 #define PXR_BASE_TF_SPIN_RW_MUTEX_H 28 #include "pxr/base/tf/api.h" 35 PXR_NAMESPACE_OPEN_SCOPE
69 static constexpr
int OneReader = 2;
70 static constexpr
int WriterFlag = 1;
82 static constexpr
int NotAcquired = 0;
83 static constexpr
int ReadAcquired = 1;
84 static constexpr
int WriteAcquired = 2;
90 , _acqState(NotAcquired) {
95 ScopedLock() : _mutex(nullptr), _acqState(NotAcquired) {}
147 _acqState = ReadAcquired;
155 _acqState = WriteAcquired;
164 _acqState = WriteAcquired;
175 _acqState = ReadAcquired;
181 void _ReleaseRead() {
184 _acqState = NotAcquired;
187 void _ReleaseWrite() {
190 _acqState = NotAcquired;
202 if (ARCH_LIKELY(!(_lockState.fetch_add(OneReader) & WriterFlag))) {
210 _lockState -= OneReader;
231 _lockState -= OneReader;
238 int state = _lockState.fetch_or(WriterFlag);
239 if (!(state & WriterFlag)) {
266 _lockState &= ~WriterFlag;
281 int state = _lockState.fetch_or(WriterFlag);
282 if (!(state & WriterFlag)) {
285 if (_lockState.fetch_sub(
286 OneReader) != (OneReader | WriterFlag)) {
306 _lockState += (OneReader-1);
314 enum _StagedAcquireWriteState {
327 _StagedAcquireWriteState
328 _StagedAcquireWriteStep(_StagedAcquireWriteState curState) {
331 case _StageNotAcquired:
332 state = _lockState.fetch_or(WriterFlag);
333 if (!(state & WriterFlag)) {
336 return state == 0 ? _StageAcquired : _StageAcquiring;
339 return _StageNotAcquired;
340 case _StageAcquiring:
343 return _StageAcquired;
346 return _StageAcquired;
350 TF_API
void _WaitForReaders()
const;
351 TF_API
void _WaitForWriter()
const;
353 std::atomic<int> _lockState;
356 PXR_NAMESPACE_CLOSE_SCOPE
358 #endif // PXR_BASE_TF_SPIN_RW_MUTEX_H #define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
bool TryAcquireWrite()
Attempt to acquire a write lock on this mutex without waiting for other writers.
bool UpgradeToWriter()
Change this lock's acquisition state from a read lock to a write lock.
ScopedLock(TfSpinRWMutex &m, bool write=true)
Construct a scoped lock for mutex m and acquire either a read or a write lock depending on write.
void AcquireWrite()
Acquire a write lock on this lock's associated mutex.
~ScopedLock()
If this scoped lock is acquired for either read or write, Release() it.
bool DowngradeToReader()
Downgrade this mutex, which must be locked for write by this thread, to being locked for read by this...
bool TryAcquireRead()
Attempt to acquire a read lock on this mutex without waiting for writers.
This class implements a readers-writer mutex and provides a scoped lock utility.
void Acquire(TfSpinRWMutex &m, bool write=true)
If the current scoped lock is acquired, Release() it, then associate this lock with m and acquire eit...
bool DowngradeToReader()
Change this lock's acquisition state from a write lock to a read lock.
Scoped lock utility class.
TfSpinRWMutex()
Construct a mutex, initially unlocked.
void ReleaseRead()
Release this thread's read lock on this mutex.
void AcquireRead()
Acquire a read lock on this mutex.
ScopedLock()
Construct a scoped lock not associated with a mutex.
void AcquireRead()
Acquire a read lock on this lock's associated mutex.
void AcquireWrite()
Acquire a write lock on this mutex.
bool UpgradeToWriter()
Upgrade this thread's lock on this mutex (which must be a read lock) to a write lock.
void Release()
Release the currently required lock on the associated mutex.
This class implements a readers-writer spin lock that emphasizes throughput when there is light conte...
void Acquire(bool write=true)
Acquire either a read or write lock on this lock's associated mutex depending on write.
void ReleaseWrite()
Release this thread's write lock on this mutex.
Stripped down version of diagnostic.h that doesn't define std::string.