30 template<
typename ExecutorType = InlineExecutor>
class TAsyncMutex {
155 }
while(next !=
nullptr);
238 if(
mMutex.
mState.compare_exchange_weak(
oldState,
reinterpret_cast<std::uintptr_t
>(
this), std::memory_order_release, std::memory_order_relaxed)) {
327 return try_lock_shared_locked(
lk);
335 return try_lock_locked(
lk);
350 if(mSharedUsers == 0) {
351 if(mHeadWaiter !=
nullptr) {
354 mState = State::Unlocked;
366 if(mHeadWaiter !=
nullptr) {
369 mState = State::Unlocked;
388 Lock(
Lock&& other)
noexcept : mMutex(std::exchange(other.mMutex,
nullptr)), mExclusive(other.mExclusive) {}
390 if(std::addressof(other) !=
this) {
391 mMutex = std::exchange(other.mMutex,
nullptr);
392 mExclusive = other.mExclusive;
399 if(mMutex !=
nullptr) {
403 mMutex->unlock_shared();
414 bool mExclusive{
false};
422 bool mExclusive =
false;
476 if(mState == State::Unlocked) {
478 mState = State::LockedShared;
482 }
else if(mState == State::LockedShared && mExclusiveWaiters == 0) {
498 if(mState == State::Unlocked) {
499 mState = State::LockedExclusive;
510 mState = State::LockedExclusive;
512 mHeadWaiter = mHeadWaiter->
mNext;
514 if(mHeadWaiter ==
nullptr) {
515 mTailWaiter =
nullptr;
520 dispatch(mExecutor, [handle =
waiterToResume->mAwaitingCoroutine]()
mutable { handle.resume(); });
524 mState = State::LockedShared;
527 mHeadWaiter = mHeadWaiter->
mNext;
528 if(mHeadWaiter ==
nullptr) {
529 mTailWaiter =
nullptr;
533 dispatch(mExecutor, [handle =
waiterToResume->mAwaitingCoroutine]()
mutable { handle.resume(); });
534 }
while(mHeadWaiter !=
nullptr && !mHeadWaiter->
mExclusive);
#define CE_ASSERT(...)
Definition Macros.hpp:323
An object that holds onto a mutex lock for its lifetime and ensures that the mutex is unlocked when i...
Definition AsyncMutex.hpp:174
Lock & operator=(const Lock &other)=delete
~Lock()
Definition AsyncMutex.hpp:189
TAsyncMutex * mMutex
Definition AsyncMutex.hpp:201
void release()
Definition AsyncMutex.hpp:195
Lock(Lock &&other) noexcept
Definition AsyncMutex.hpp:178
Lock(TAsyncMutex &mutex, std::adopt_lock_t) noexcept
Definition AsyncMutex.hpp:176
Lock(const Lock &other)=delete
void unlock()
Definition AsyncMutex.hpp:192
Lock & operator=(Lock &&other) noexcept
Definition AsyncMutex.hpp:179
Definition AsyncMutex.hpp:204
LockOperation(TAsyncMutex &mutex) noexcept
Definition AsyncMutex.hpp:221
void await_resume() const noexcept
Definition AsyncMutex.hpp:245
LockOperation * mNext
The next LockOperation in the chain.
Definition AsyncMutex.hpp:210
CoroutineHandle mAwaiter
The coroutine handle to the awaiter that is waiting for the lock.
Definition AsyncMutex.hpp:214
TAsyncMutex & mMutex
The ´AsyncMutex` that the lock operations belongs to.
Definition AsyncMutex.hpp:218
bool await_suspend(const CoroutineHandle<> awaiter) noexcept
Definition AsyncMutex.hpp:225
bool await_ready() const noexcept
Definition AsyncMutex.hpp:224
Definition AsyncMutex.hpp:248
Lock await_resume() const noexcept
Definition AsyncMutex.hpp:252
A mutex that can be locked asynchronously using 'co_await'.
Definition AsyncMutex.hpp:30
static constexpr std::uintptr_t kLockedNoWaiters
Definition AsyncMutex.hpp:43
ScopedLockOperation scopedLock() noexcept
Acquire a lock on the mutex asynchronously, returning an object that will call unlock() automatically...
Definition AsyncMutex.hpp:122
LockOperation lock() noexcept
Acquire a lock on the mutex asynchronously.
Definition AsyncMutex.hpp:108
~TAsyncMutex() noexcept
Destroys the mutex.
Definition AsyncMutex.hpp:77
TAsyncMutex() noexcept=default
Construct to a mutex that is not currently locked.
static constexpr std::uintptr_t kNotLocked
Definition AsyncMutex.hpp:42
bool tryLock() noexcept
Attempt to acquire a lock on the mutex without blocking.
Definition AsyncMutex.hpp:89
void unlock()
Unlock the mutex.
Definition AsyncMutex.hpp:131
Atomic< std::uintptr_t > mState
This field provides synchronisation for the mutex.
Definition AsyncMutex.hpp:56
ExecutorType mExecutor
This executor is for resuming multiple shared waiters.
Definition AsyncMutex.hpp:40
LockOperation * mWaiters
Linked list of async lock operations that are waiting to acquire the mutex.
Definition AsyncMutex.hpp:61
bool try_lock() noexcept
Attempt to acquire a lock on the mutex without blocking.
Definition AsyncMutex.hpp:96
A scoped RAII lock holder for a AsyncSharedMutex.
Definition AsyncMutex.hpp:378
Lock & operator=(Lock &&other) noexcept
Definition AsyncMutex.hpp:389
bool isExclusive() const noexcept
Definition AsyncMutex.hpp:410
Lock(TAsyncSharedMutex &sm, const bool exclusive)
Definition AsyncMutex.hpp:380
Lock & operator=(const Lock &)=delete
void unlock()
Unlocks the shared mutex prior to this lock going out of scope.
Definition AsyncMutex.hpp:398
Lock(Lock &&other) noexcept
Definition AsyncMutex.hpp:388
~Lock()
Unlocks the mutex upon this shared scoped lock destructing.
Definition AsyncMutex.hpp:383
Lock(const Lock &)=delete
Definition AsyncMutex.hpp:417
LockOperation * mNext
Definition AsyncMutex.hpp:424
CoroutineHandle mAwaitingCoroutine
Definition AsyncMutex.hpp:423
LockOperation(TAsyncSharedMutex &sm, const bool exclusive)
Definition AsyncMutex.hpp:427
bool await_suspend(const CoroutineHandle<> awaitingCoroutine) noexcept
Definition AsyncMutex.hpp:437
TAsyncSharedMutex & mMutex
Definition AsyncMutex.hpp:421
friend class TAsyncSharedMutex
Definition AsyncMutex.hpp:418
bool await_ready() const noexcept
Definition AsyncMutex.hpp:429
bool mExclusive
Definition AsyncMutex.hpp:422
Lock await_resume() noexcept
Definition AsyncMutex.hpp:471
Definition AsyncMutex.hpp:263
LockOperation lock_shared()
Locks the mutex in a shared state.
Definition AsyncMutex.hpp:312
void unlock_shared()
Unlocks a single shared state user.
Definition AsyncMutex.hpp:345
TAsyncSharedMutex & operator=(const TAsyncSharedMutex &)=delete
bool try_lock()
Definition AsyncMutex.hpp:332
void wakeWaiters(UniqueLock< Mutex > &lk)
Definition AsyncMutex.hpp:506
friend class LockOperation
Definition AsyncMutex.hpp:269
TAsyncSharedMutex(const TAsyncSharedMutex &)=delete
LockOperation * mTailWaiter
Definition AsyncMutex.hpp:291
Mutex mMutex
Definition AsyncMutex.hpp:280
LockOperation * mHeadWaiter
Definition AsyncMutex.hpp:290
auto try_lock_shared() -> bool
Definition AsyncMutex.hpp:319
bool try_lock_shared_locked(UniqueLock< Mutex > &lk)
Definition AsyncMutex.hpp:475
State
Definition AsyncMutex.hpp:271
TAsyncSharedMutex()
Creates a new async shared mutex.
Definition AsyncMutex.hpp:295
TAsyncSharedMutex & operator=(TAsyncSharedMutex &&)=delete
TAsyncSharedMutex(ExecutorType &&executor)
Definition AsyncMutex.hpp:301
~TAsyncSharedMutex()=default
void unlock()
Unlocks the mutex from its exclusive state.
Definition AsyncMutex.hpp:364
bool try_lock_locked(UniqueLock< Mutex > &lk)
Definition AsyncMutex.hpp:497
TAsyncSharedMutex(TAsyncSharedMutex &&)=delete
uint64_t mExclusiveWaiters
The current number of exclusive waiters waiting to acquire the lock.
Definition AsyncMutex.hpp:288
LockOperation lock()
Locks the mutex in an exclusive state.
Definition AsyncMutex.hpp:315
ExecutorType mExecutor
This executor is for resuming multiple shared waiters.
Definition AsyncMutex.hpp:278
The class UniqueLock is a general-purpose mutex ownership wrapper allowing deferred locking,...
Definition Threading.hpp:270
Definition Application.hpp:19
std::coroutine_handle< T > CoroutineHandle
A type alias to the C++ standard library coroutine handle.
Definition Coroutine.hpp:26
std::mutex Mutex
The Mutex class is a synchronization primitive that can be used to protect shared data from being sim...
Definition Threading.hpp:73
struct CeresEngine::GLState state
std::atomic< T > Atomic
The Atomic template defines an atomic type.
Definition Atomic.hpp:16
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25