shithub: mc

Download patch

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")