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