ref: b9656ec7e120d1fced20ea5ca826c57f2de4fc84
dir: /lib/thread/condvar+freebsd.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) } /* `umtx_op` fully supports implementing condvars efficiently but also requires condvars to be implemented in a specific way. For now we'll just invite the thundering herd. */ const condbroadcast = {cond : cond# xadd(&cond._seq, 1) ftxwakeall(&cond._seq) }