summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-18 00:13:00 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-18 00:26:14 -0700
commitbfeac2fcc8ec3ae417a2ad54b2b40d6a4b4b2754 (patch)
tree1dda87aa58c0f57b3c81c1ac2967c2aa3cb434a8
parent1fd6d73d4da455a2ded723e320c7451d5076eb83 (diff)
downloadmc-bfeac2fcc8ec3ae417a2ad54b2b40d6a4b4b2754.tar.gz
Fix condvars to use requeue.
The docs are wrong. Fuck.
-rw-r--r--lib/thread/condvar+linux.myr18
-rw-r--r--lib/thread/test/condvar.myr1
2 files changed, 15 insertions, 4 deletions
diff --git a/lib/thread/condvar+linux.myr b/lib/thread/condvar+linux.myr
index 5d30274..fe00408 100644
--- a/lib/thread/condvar+linux.myr
+++ b/lib/thread/condvar+linux.myr
@@ -32,9 +32,14 @@ const condwait = {cond
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 condsignal = {cond : cond#
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)
}
diff --git a/lib/thread/test/condvar.myr b/lib/thread/test/condvar.myr
index 94cda94..e8670b1 100644
--- a/lib/thread/test/condvar.myr
+++ b/lib/thread/test/condvar.myr
@@ -41,7 +41,6 @@ const main = {
;;
thread.condbroadcast(&cv)
while nwoken != 100
- std.put("{}\n", nwoken)
/* nothing */
;;
std.assert(nwoken == 100, "wrong thread count woken")