Loading...
Searching...
No Matches
spinMutex.h
1//
2// Copyright 2023 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_TF_SPIN_MUTEX_H
8#define PXR_BASE_TF_SPIN_MUTEX_H
9
10#include "pxr/pxr.h"
11#include "pxr/base/tf/api.h"
12
13#include "pxr/base/arch/hints.h"
15
16#include <atomic>
17
18PXR_NAMESPACE_OPEN_SCOPE
19
42{
43public:
44
46 TfSpinMutex() : _lockState(false) {}
47
50 struct ScopedLock {
51
53 explicit ScopedLock(TfSpinMutex &m) : _mutex(&m) {
54 Acquire();
55 }
56
58 ScopedLock() = default;
59
62 Release();
63 }
64
68 Release();
69 _mutex = &m;
70 Acquire();
71 }
72
75 void Release() {
76 if (_acquired) {
77 _Release();
78 }
79 }
80
83 void Acquire() {
84 TF_DEV_AXIOM(_mutex);
85 TF_DEV_AXIOM(!_acquired);
86 _mutex->Acquire();
87 _acquired = true;
88 }
89
94 Release();
95 _mutex = &m;
96 return TryAcquire();
97 }
98
102 bool TryAcquire() {
103 TF_DEV_AXIOM(_mutex);
104 TF_DEV_AXIOM(!_acquired);
105 _acquired = _mutex->TryAcquire();
106 return _acquired;
107 }
108
109 private:
110
111 void _Release() {
112 TF_DEV_AXIOM(_acquired);
113 _mutex->Release();
114 _acquired = false;
115 }
116
117 TfSpinMutex *_mutex = nullptr;
118 bool _acquired = false;
119 };
120
125 inline bool TryAcquire() {
126 return _lockState.exchange(true, std::memory_order_acquire) == false;
127 }
128
132 void Acquire() {
133 if (ARCH_LIKELY(TryAcquire())) {
134 return;
135 }
136 _AcquireContended();
137 }
138
140 inline void Release() {
141 _lockState.store(false, std::memory_order_release);
142 }
143
144private:
145
146 TF_API void _AcquireContended();
147
148 std::atomic<bool> _lockState;
149};
150
151PXR_NAMESPACE_CLOSE_SCOPE
152
153#endif // PXR_BASE_TF_SPIN_MUTEX_H
This class implements a simple spin lock that emphasizes throughput when there is little to no conten...
Definition: spinMutex.h:42
TfSpinMutex()
Construct a mutex, initially unlocked.
Definition: spinMutex.h:46
void Release()
Release this thread's lock on this mutex.
Definition: spinMutex.h:140
void Acquire()
Acquire a lock on this mutex.
Definition: spinMutex.h:132
bool TryAcquire()
Acquire a lock on this mutex if it is not currently held by another thread.
Definition: spinMutex.h:125
Stripped down version of diagnostic.h that doesn't define std::string.
#define TF_DEV_AXIOM(cond)
The same as TF_AXIOM, but compiled only in dev builds.
Definition: diagnostic.h:205
Compiler hints.
Scoped lock utility class.
Definition: spinMutex.h:50
void Acquire(TfSpinMutex &m)
If the current scoped lock is acquired, Release() it, then associate this lock with m and acquire a l...
Definition: spinMutex.h:67
ScopedLock()=default
Construct a scoped lock not associated with a mutex.
void Release()
Release the currently required lock on the associated mutex.
Definition: spinMutex.h:75
ScopedLock(TfSpinMutex &m)
Construct a scoped lock for mutex m and acquire a lock.
Definition: spinMutex.h:53
void Acquire()
Acquire a lock on this lock's associated mutex.
Definition: spinMutex.h:83
~ScopedLock()
If this scoped lock is acquired, Release() it.
Definition: spinMutex.h:61
bool TryAcquire(TfSpinMutex &m)
If the current scoped lock is acquired, Release() it, then associate this lock with m and try to acqu...
Definition: spinMutex.h:93
bool TryAcquire()
Try to acquire a lock on this lock's associated mutex.
Definition: spinMutex.h:102