diff options
author | serxa <serxa@yandex-team.ru> | 2022-02-10 16:49:08 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:49:08 +0300 |
commit | e5d4696304c6689379ac7ce334512404d4b7836c (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/lwtrace/rwspinlock.h | |
parent | d6d7db348c2cc64e71243cab9940ee6778f4317d (diff) | |
download | ydb-e5d4696304c6689379ac7ce334512404d4b7836c.tar.gz |
Restoring authorship annotation for <serxa@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/lwtrace/rwspinlock.h')
-rw-r--r-- | library/cpp/lwtrace/rwspinlock.h | 170 |
1 files changed, 85 insertions, 85 deletions
diff --git a/library/cpp/lwtrace/rwspinlock.h b/library/cpp/lwtrace/rwspinlock.h index bd04e2120f3..7c518ec49e4 100644 --- a/library/cpp/lwtrace/rwspinlock.h +++ b/library/cpp/lwtrace/rwspinlock.h @@ -1,88 +1,88 @@ -#pragma once - -#include <util/system/spinlock.h> - -// State can be one of: -// 0) [NOT_USED] State = 0: -// * any reader can acquire lock (State += 2: -> READING) -// * one writer can acquire lock (State = -1: -> WRITING) -// 1) [READING] even number: -// * State/2 = number of active readers -// * no writers are waiting -// * any reader can aqcuire lock (State += 2: -> READING) -// * active readers can release lock (State -= 2) -// * one writer can acquire lock (State += 1: -> WAITING) -// 2) [WAITING] odd number > 0: -// * (State-1)/2 = number of active readers -// * no more readers/writers can acquire lock -// * active readers can release lock (State -= 2: -> WAITING) -// * exactly one writer is waiting for active readers to release lock -// * if no more active readers left (State == 1) waiting writer acquires lock (State = -1: -> WRITING) -// 3) [WRITING] State = -1 -// * exactly one active writer -// * no active readers -// * no more readers/writers can acquire lock -// * writer can release lock (State = 0: -> READING) - -struct TRWSpinLock { - TAtomic State; // must be initialized by 'TRWSpinLock myLock = {0};' construction - - void Init() noexcept { - State = 0; - } - - void AcquireRead() noexcept { - while (true) { - TAtomic a = AtomicGet(State); - if ((a & 1) == 0 && AtomicCas(&State, a + 2, a)) { - break; - } - SpinLockPause(); - } - } - - void ReleaseRead() noexcept { - AtomicAdd(State, -2); - } - - void AcquireWrite() noexcept { - while (true) { - TAtomic a = AtomicGet(State); - if ((a & 1) == 0 && AtomicCas(&State, a + 1, a)) { - break; - } - SpinLockPause(); - } - +#pragma once + +#include <util/system/spinlock.h> + +// State can be one of: +// 0) [NOT_USED] State = 0: +// * any reader can acquire lock (State += 2: -> READING) +// * one writer can acquire lock (State = -1: -> WRITING) +// 1) [READING] even number: +// * State/2 = number of active readers +// * no writers are waiting +// * any reader can aqcuire lock (State += 2: -> READING) +// * active readers can release lock (State -= 2) +// * one writer can acquire lock (State += 1: -> WAITING) +// 2) [WAITING] odd number > 0: +// * (State-1)/2 = number of active readers +// * no more readers/writers can acquire lock +// * active readers can release lock (State -= 2: -> WAITING) +// * exactly one writer is waiting for active readers to release lock +// * if no more active readers left (State == 1) waiting writer acquires lock (State = -1: -> WRITING) +// 3) [WRITING] State = -1 +// * exactly one active writer +// * no active readers +// * no more readers/writers can acquire lock +// * writer can release lock (State = 0: -> READING) + +struct TRWSpinLock { + TAtomic State; // must be initialized by 'TRWSpinLock myLock = {0};' construction + + void Init() noexcept { + State = 0; + } + + void AcquireRead() noexcept { + while (true) { + TAtomic a = AtomicGet(State); + if ((a & 1) == 0 && AtomicCas(&State, a + 2, a)) { + break; + } + SpinLockPause(); + } + } + + void ReleaseRead() noexcept { + AtomicAdd(State, -2); + } + + void AcquireWrite() noexcept { + while (true) { + TAtomic a = AtomicGet(State); + if ((a & 1) == 0 && AtomicCas(&State, a + 1, a)) { + break; + } + SpinLockPause(); + } + while (!AtomicCas(&State, TAtomicBase(-1), 1)) { - SpinLockPause(); - } - } - - void ReleaseWrite() noexcept { - AtomicSet(State, 0); - } -}; - -struct TRWSpinLockReadOps { - static inline void Acquire(TRWSpinLock* t) noexcept { - t->AcquireRead(); - } - - static inline void Release(TRWSpinLock* t) noexcept { - t->ReleaseRead(); - } -}; - -struct TRWSpinLockWriteOps { - static inline void Acquire(TRWSpinLock* t) noexcept { - t->AcquireWrite(); - } - - static inline void Release(TRWSpinLock* t) noexcept { - t->ReleaseWrite(); - } -}; - + SpinLockPause(); + } + } + + void ReleaseWrite() noexcept { + AtomicSet(State, 0); + } +}; + +struct TRWSpinLockReadOps { + static inline void Acquire(TRWSpinLock* t) noexcept { + t->AcquireRead(); + } + + static inline void Release(TRWSpinLock* t) noexcept { + t->ReleaseRead(); + } +}; + +struct TRWSpinLockWriteOps { + static inline void Acquire(TRWSpinLock* t) noexcept { + t->AcquireWrite(); + } + + static inline void Release(TRWSpinLock* t) noexcept { + t->ReleaseWrite(); + } +}; + using TReadSpinLockGuard = TGuard<TRWSpinLock, TRWSpinLockReadOps>; using TWriteSpinLockGuard = TGuard<TRWSpinLock, TRWSpinLockWriteOps>; |