ref: 38727e953df2c11f5600ea6f3142ec4366fce3cf
dir: /lib/thread/condvar+osx.myr/
use std use "atomic" use "common" 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 seq var mtx mtx = cond._mtx seq = cond._seq mtxunlock(mtx) /* FIXME?: `ftxwait` can be interrupted but `condwait` should always be done in a loop anyway. */ ftxwait(&cond._seq, seq, Zptr) 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) }