ref: 847f11bb87ebfa7e4de48c05d65c83758d9220e1
dir: /lib/thread/condvar+osx.myr/
use std use "atomic" use "mutex" use "futex" pkg thread = type cond = struct _mtx : mutex# _seq : ftxtag ;; const mkcond : (mtx : mutex# -> cond) const condwait : (cond : cond# -> void) const condsignal : (cond : cond# -> void) const condbroadcast : (cond : cond# -> void) ;; const mkcond = {mtx -> [._mtx = mtx, ._seq = 0] } const condwait = {cond var mtx = cond._mtx var seq = xget(&cond._seq) mtxunlock(mtx) ftxwait(&cond._seq, seq, -1) /* In the event of a broadcast, we aren't requeueing waiters from the condvar's futex to the mutex's futex so we can just reacquire the mutex normally. */ mtxlock(mtx) } const condsignal = {cond : cond# xadd(&cond._seq, 1) ftxwake(&cond._seq) } /* Yes, this invites the thundering herd but that's what OS X gets for not having a requeue operation. */ const condbroadcast = {cond : cond# xadd(&cond._seq, 1) ftxwakeall(&cond._seq) }