CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
futex.h
1#pragma once
2
3#include <cx/cx.h>
4#include <cx/thread/atomic.h>
5
6enum FUTEX_Status {
7 FUTEX_Error = 0, // unexpected error
8 FUTEX_Waited = 0x1, // successfully waited for wakeup
9 FUTEX_Retry = 0x2, // old value was not what was expected, try again
10 FUTEX_Timeout = 0x4, // timeout reached
11};
12#define FUTEX_LOOP 0x3 // convenient mask for certain futex loops (Waited or Retry)
13
14typedef struct Futex {
15 atomic(int32) val;
16 atomic(uint16) _ps; // platform-specific value
17 atomic(uint8) _ps_lock; // _ps spinlock
18} Futex;
19
20_Static_assert(sizeof(Futex) <= sizeof(int64), "Invalid Futex structure packing");
21
22void futexInit(_Out_ Futex *ftx, int32 val);
23
24_meta_inline int32 futexVal(_Inout_ Futex *ftx) {
25 return atomicLoad(int32, &ftx->val, Relaxed);
26}
27
28// sets the value but does NOT wake up any waiting threads; use with caution
29// and pair with either futexWake or futexWakeAll
30_meta_inline void futexSet(_Inout_ Futex *ftx, int32 val) {
31 atomicStore(int32, &ftx->val, val, Relaxed);
32}
33
34// If futex value is equal to oldval, puts the thread to sleep until futexWake
35// is called on the same futex, or until the timeout expires.
36// Returns true only if the thread actually slept.
37int futexWait(_Inout_ Futex *ftx, int32 oldval, int64 timeout);
38
39void futexWake(_Inout_ Futex *ftx);
40void futexWakeMany(_Inout_ Futex *ftx, int count);
41void futexWakeAll(_Inout_ Futex *ftx);