//////////////////////////////////////////////////////////// //~ Neq futex types Struct(FutexNeqList) { FutexNeqList *prev; FutexNeqList *next; volatile void *addr; i16 first; }; Struct(FutexNeqListBin) { TicketMutex tm; FutexNeqList *first; FutexNeqList *first_free; }; //////////////////////////////////////////////////////////// //~ State types #define FutexNeqBinsCount 16384 #define FutexGteBinsCount 16384 AlignedStruct(FiberNeqFutexState, CachelineSize) { i16 next; }; Struct(SharedFutexState) { FiberNeqFutexState fiber_neq_states[MaxFibers]; FutexNeqListBin neq_bins[FutexNeqBinsCount]; } extern shared_futex_state; //////////////////////////////////////////////////////////// //~ Startup void InitFutexSystem(void); //////////////////////////////////////////////////////////// //~ State helpers FiberNeqFutexState *FiberNeqFutexStateFromId(i16 fiber_id); //////////////////////////////////////////////////////////// //~ Not-equal futex operations /* Similar to Win32 WaitOnAddress & WakeByAddressAll * i.e. - Suprious wait until value at address != cmp */ void FutexYieldNeq(volatile void *addr, void *cmp, u8 cmp_size); void FutexWakeNeq(void *addr); //////////////////////////////////////////////////////////// //~ Greater-than-or-equal futex operations /* Similar to Win32 WaitOnAddress & WakeByAddressAll * i.e. - Spurious wait until monotonically increasing value at address >= cmp (used for fences) * * NOTE: This API is offered for fence-like semantics, where waiters only want to * wake when the futex progresses past the specified target value, rather than * wake every time the futex is modified. **/ void FutexYieldGte(volatile void *addr, void *cmp, u8 cmp_size); void FutexWakeGte(void *addr);