shithub: mc

Download patch

ref: aa9e46aae152515edaf54c41c33b73eee550fec0
parent: 8e0443da2f98080d20efe818af4184b5ccb2ce73
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jan 4 18:34:25 EST 2016

Implement freebsd condition variables.

--- a/lib/thread/bld.proj
+++ b/lib/thread/bld.proj
@@ -3,14 +3,15 @@
 
 	# linux impl of basic thread primitives
 	condvar+linux.myr
+	future+linux.myr
 	mutex+linux.myr
 	spawn+linux.myr
-	future+linux.myr
 	exit+linux-x64.s
 
 	# freebsd impl of thread primitives
-	spawn+freebsd.myr
+	condvar+freebsd.myr
 	mutex+freebsd.myr
+	spawn+freebsd.myr
 	exit+freebsd-x64.s
 
 	atomic-impl+x64.s
--- /dev/null
+++ b/lib/thread/condvar+freebsd.myr
@@ -1,0 +1,59 @@
+use std
+use sys
+
+use "atomic.use"
+use "common.use"
+use "mutex.use"
+
+pkg thread =
+	type cond = struct
+		_mtx	: mutex#
+		_seq	: uint32
+	;;
+
+	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 seq
+	var mtx
+
+	mtx = cond._mtx
+	seq = cond._seq
+
+	mtxunlock(mtx)
+	sys.umtx_op(&cond._seq castto(void#), \
+		sys.Umtxwaituintpriv, \
+		seq castto(uint64), \
+		Zptr, Zptr)
+
+	/*
+	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.umtx_op(&mtx._state castto(void#), \
+			sys.Umtxwaituintpriv, \
+			Contended castto(uint64), \
+			Zptr, Zptr)
+	;;
+}
+
+const condsignal = {cond : cond#
+	xadd(&cond._seq, 1)
+	sys.umtx_op(&cond._seq castto(void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
+}
+
+const condbroadcast = {cond : cond#
+	xadd(&cond._seq, 1)
+	sys.umtx_op(&cond._seq castto(void#), sys.Umtxwakepriv, 0x7ffffff, Zptr, Zptr)
+}
+