summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/thread/bld.proj5
-rw-r--r--lib/thread/condvar+freebsd.myr59
2 files changed, 62 insertions, 2 deletions
diff --git a/lib/thread/bld.proj b/lib/thread/bld.proj
index 562cf29..c4aa392 100644
--- a/lib/thread/bld.proj
+++ b/lib/thread/bld.proj
@@ -3,14 +3,15 @@ lib thread =
# 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
diff --git a/lib/thread/condvar+freebsd.myr b/lib/thread/condvar+freebsd.myr
new file mode 100644
index 0000000..eb04866
--- /dev/null
+++ b/lib/thread/condvar+freebsd.myr
@@ -0,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)
+}
+