//////////////////////////////////////////////////////////// //~ Mutex types #define DefaultMutexSpin 4000 AlignedStruct(Mutex, CachelineSize) { /* Bit 31 = Exclusive lock is held * Bit 30 = Exclusive lock is pending * Bit 0-30 = Shared locks count */ Atomic32 v; #if RtcIsEnabled Atomic32 exclusive_fiber_id; #endif }; StaticAssert(alignof(Mutex) == CachelineSize && sizeof(Mutex) % CachelineSize == 0); Struct(Lock) { Mutex *mutex; b32 exclusive; }; //////////////////////////////////////////////////////////// //~ Condition variable types AlignedStruct(Cv, CachelineSize) { Atomic64 wake_gen; }; StaticAssert(alignof(Cv) == CachelineSize && sizeof(Cv) % CachelineSize == 0); //////////////////////////////////////////////////////////// //~ Fence types Struct(Fence) { Atomic64Padded v; }; //////////////////////////////////////////////////////////// //~ Mutex operations Lock LockSpinE(Mutex *m, i32 spin); Lock LockSpinS(Mutex *m, i32 spin); Lock LockE(Mutex *m); Lock LockS(Mutex *m); void Unlock(Lock *lock); //- Lock assertion #if RtcIsEnabled # define AssertLockedE(l, m) Assert((l)->mutex == (m) && (l)->exclusive == 1) # define AssertLockedES(l, m) Assert((l)->mutex == (m)) #else # define AssertLockedE(l, m) LAX l # define AssertLockedES(l, m) LAX l #endif //////////////////////////////////////////////////////////// //~ Condition variable operations void YieldOnCv(Cv *cv, Lock *lock); void SignalCv(Cv *cv); //////////////////////////////////////////////////////////// //~ Fence operations i64 FetchFence(Fence *fence); void SetFence(Fence *fence, i64 x); i64 FetchSetFence(Fence *fence, i64 x); i64 FetchAddFence(Fence *fence, i64 x); i64 YieldOnFence(Fence *fence, i64 target);