ref: 92847c0604e5f4fa790b1783595e8a503ad271be
dir: /lib/thread/sem+futex.myr/
use std use "atomic" use "common" use "futex" pkg thread = type sem = struct _val : ftxtag ;; 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 for ; ; while (v = s._val) > 0 if xcas(&s._val, v, v - 1) == v -> void ;; ;; ftxwait(&s._val, v, Zptr) ;; } 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") /* Unconditionally wake one waiter */ ftxwake(&s._val) }