power_play/src/base/base_snc.h
2025-09-18 10:16:57 -05:00

78 lines
1.6 KiB
C

////////////////////////////////
//~ 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);