ref: e1e9167cc8b847dfb3b37df4dc041d20ac271010
dir: /lib/thread/condvar+openbsd:6.2.myr/
use std
use sys
use "atomic"
use "common"
use "futex"
use "mutex"
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 need to atomically set the mutex to
contended. This allows us to pass responsibility for waking up the
potential other waiters from the requeue operation on to the unlocker
of the mutex.
*/
mtxcontended(mtx)
}
const condsignal = {cond : cond#
xadd(&cond._seq, 1)
ftxwake(&cond._seq)
}
const condbroadcast = {cond : cond#
xadd(&cond._seq, 1)
sys.futex((&cond._seq : uint32#), sys.Futexrequeue, 1,
(0x7fffffff : sys.timespec#),
(&cond._mtx._state : uint32#))
}