ref: e6811668a36f0bfaa6abe113bc25ed99473f8973
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#))
}