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