ref: 178ce0afad1d2ec8af4814ce5970d2e8194b849f
dir: /lib/thread/sem+futex.myr/
use std use "atomic" use "futex" pkg thread = type sem = struct _val : ftxtag _nwaiters : uint32 ;; const mksem : (v : uint32 -> sem) const semwait : (s : sem# -> void) const semtrywait : (s : sem# -> bool) const sempost : (s : sem# -> void) ;; const mksem = {v -> [._val = (v : ftxtag)] } const semwait = {s var v = 0 xadd(&s._nwaiters, 1) for ; ; while (v = s._val) > 0 if xcas(&s._val, v, v - 1) == v xadd(&s._nwaiters, -1) -> void ;; ;; ftxwait(&s._val, v, -1) ;; } const semtrywait = {s for ; ; var v = xget(&s._val) if v == 0 -> false ;; if xcas(&s._val, v, v - 1) == v -> true ;; ;; -> false /* Unreachable */ } const sempost = {s std.assert((xadd(&s._val, 1) : uint32) != ~0x0, "error: semaphore overflowed\n") if xget(&s._nwaiters) > 0 ftxwake(&s._val) ;; }