ref: bfeac2fcc8ec3ae417a2ad54b2b40d6a4b4b2754
parent: 1fd6d73d4da455a2ded723e320c7451d5076eb83
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Sep 17 20:13:00 EDT 2015
Fix condvars to use requeue. The docs are wrong. Fuck.
--- a/lib/thread/condvar+linux.myr
+++ b/lib/thread/condvar+linux.myr
@@ -32,9 +32,14 @@
mtxunlock(mtx)
sys.futex(&cond._seq, sys.Futexwait | sys.Futexpriv, seq, Zptr, Zptr, 0)
- /* We need to atomically set the mutex to contended */
+ /*
+ We need to atomically set the mutex to contended. This allows us to
+ pass responsibility for waking up the potential other waiters on to the
+ unlocker of the mutex.
+ */
while xchg(&mtx._state, Contended) != Unlocked
- sys.futex(&mtx._state, sys.Futexwait | sys.Futexpriv, Contended, Zptr, Zptr, 0)
+ sys.futex(&mtx._state, sys.Futexwait | sys.Futexpriv, \
+ Contended, Zptr, Zptr, 0)
;;
}
@@ -45,6 +50,13 @@
const condbroadcast = {cond : cond#
xadd(&cond._seq, 1)
- sys.futex(&cond._seq, sys.Futexwake | sys.Futexpriv, 0x7fffffff, Zptr, Zptr, 0)
+ /*
+ The futex docs seem to be broken -- the timeout parameter seems to be
+ used for the number of threads to move, and is not ignored when
+ requeueing
+ */
+ sys.futex(&cond._seq, sys.Futexcmprequeue | sys.Futexpriv, \
+ 1, 0x7fffffff castto(sys.timespec#), \
+ &cond._mtx._state, cond._seq)
}
--- a/lib/thread/test/condvar.myr
+++ b/lib/thread/test/condvar.myr
@@ -41,7 +41,6 @@
;;
thread.condbroadcast(&cv)
while nwoken != 100
- std.put("{}\n", nwoken)
/* nothing */
;;
std.assert(nwoken == 100, "wrong thread count woken")