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