7 #ifndef PXR_BASE_TF_SPIN_RW_MUTEX_H
8 #define PXR_BASE_TF_SPIN_RW_MUTEX_H
53 static constexpr
int OneReader = 2;
54 static constexpr
int WriterFlag = 1;
76 , _acqState(_NotAcquired) {
84 : _mutex(&m), _acqState(_NotAcquired) {}
87 ScopedLock() : _mutex(nullptr), _acqState(_NotAcquired) {}
92 : _mutex(std::
exchange(other._mutex,
nullptr))
93 , _acqState(std::
exchange(other._acqState, _NotAcquired)) {}
100 if (
this != &other) {
177 _acqState = _ReadAcquired;
187 _acqState = _ReadAcquired;
199 _acqState = _WriteAcquired;
213 _acqState = _WriteAcquired;
228 _acqState = _WriteAcquired;
242 _acqState = _WriteAcquired;
254 _acqState = _ReadAcquired;
261 static constexpr
int _NotAcquired = 0;
262 static constexpr
int _ReadAcquired = 1;
263 static constexpr
int _WriteAcquired = 2;
265 void _ReleaseRead() {
268 _acqState = _NotAcquired;
271 void _ReleaseWrite() {
274 _acqState = _NotAcquired;
289 OneReader, std::memory_order_acquire) &
298 _lockState.fetch_sub(OneReader, std::memory_order_release);
320 _lockState.fetch_sub(OneReader, std::memory_order_release);
331 int state = _lockState.fetch_or(WriterFlag, std::memory_order_acquire);
332 if (!(state & WriterFlag)) {
349 return _lockState.compare_exchange_strong(
350 expected, WriterFlag,
351 std::memory_order_acquire,
352 std::memory_order_relaxed);
371 _lockState.fetch_and(~WriterFlag, std::memory_order_release);
384 const auto acquire = std::memory_order_acquire;
385 const auto release = std::memory_order_release;
388 int state = _lockState.fetch_or(WriterFlag, acquire);
389 if (!(state & WriterFlag)) {
393 if (_lockState.fetch_sub(
394 OneReader, release) != (OneReader | WriterFlag)) {
422 _lockState.fetch_add(OneReader - 1, std::memory_order_acq_rel);
430 enum _StagedAcquireWriteState {
443 _StagedAcquireWriteState
444 _StagedAcquireWriteStep(_StagedAcquireWriteState curState) {
447 case _StageNotAcquired:
448 state = _lockState.fetch_or(WriterFlag, std::memory_order_acquire);
449 if (!(state & WriterFlag)) {
452 return state == 0 ? _StageAcquired : _StageAcquiring;
455 return _StageNotAcquired;
456 case _StageAcquiring:
459 return _StageAcquired;
462 return _StageAcquired;
466 TF_API void _WaitForReaders()
const;
467 TF_API void _WaitForWriter()
const;
469 std::atomic<int> _lockState;
474 #endif // PXR_BASE_TF_SPIN_RW_MUTEX_H
ScopedLock()
Construct a scoped lock not associated with a mutex.
#define PXR_NAMESPACE_OPEN_SCOPE
bool TryAcquireWriteIfReleased()
ScopedLock(TfSpinRWMutex &m, TfSpinRWMutex::DeferAcquire)
**But if you need a result
ScopedLock(ScopedLock &&other) noexcept
bool TryAcquire(TfSpinRWMutex &m, bool write=true)
ScopedLock & operator=(ScopedLock &&other) noexcept
void Acquire(bool write=true)
#define TF_DEV_AXIOM(cond)
bool TryAcquire(bool write=true)
bool TryAcquireWriteIfReleased()
static constexpr DeferAcquire deferAcquire
Tag value for deferred-acquisition ScopedLock construction.
VULKAN_HPP_CONSTEXPR_14 VULKAN_HPP_INLINE T exchange(T &obj, U &&newValue)
TfSpinRWMutex()
Construct a mutex, initially unlocked.
#define PXR_NAMESPACE_CLOSE_SCOPE
void ReleaseWrite()
Release this thread's write lock on this mutex.
void ReleaseRead()
Release this thread's read lock on this mutex.
ScopedLock(TfSpinRWMutex &m, bool write=true)
void Acquire(TfSpinRWMutex &m, bool write=true)