//////////////////////////////////////////////////////////// //~ Mutex types #define DefaultMutexSpin 4000 AlignedStruct(Mutex, IsolationSize) { // Bit 31 = Exclusive lock is held // Bit 30 = Exclusive lock is pending // Bit 0-30 = Shared locks count Atomic32 v; Atomic32 exclusive_thread_id; }; Struct(Lock) { Mutex *mutex; b32 exclusive; }; //////////////////////////////////////////////////////////// //~ Condition variable types AlignedStruct(Cv, IsolationSize) { Atomic64 wake_gen; }; //////////////////////////////////////////////////////////// //~ Fence types Struct(Fence) { IsolatedAtomic64 v; }; //////////////////////////////////////////////////////////// //~ Lazy init types Struct(LazyInitBarrier) { // 0 = untouched // 1 = initializing // 2 = initialized IsolatedAtomic32 v; }; //////////////////////////////////////////////////////////// //~ Mutex Lock ExclusiveLockEx(Mutex *m, i32 spin); Lock SharedLockEx(Mutex *m, i32 spin); Lock LockE(Mutex *m); Lock LockS(Mutex *m); void Unlock(Lock *lock); //- Lock assertion #if IsRtcEnabled #define AssertLockedE(l, m) Assert((l)->mutex == (m) && (l)->exclusive == 1) #define AssertLockedES(l, m) Assert((l)->mutex == (m)) #else #define AssertLockedE(l, m) #define AssertLockedES(l, m) #endif //////////////////////////////////////////////////////////// //~ Condition variable void YieldOnCv(Cv *cv, Lock *lock); void SignalCv(Cv *cv); //////////////////////////////////////////////////////////// //~ Fence 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); //////////////////////////////////////////////////////////// //~ Lazy init b32 BeginLazyInit(LazyInitBarrier *barrier); void EndLazyInit(LazyInitBarrier *barrier);