ref: 61fc99f4d1bb75a6ac88cf5395f37f735589b4ce
parent: 466e33d95d9da9d218952c836d99c75ac2142b05
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Sep 23 04:31:57 EDT 2017
Implement OpenBSD 6.2 futex mutexes.
--- a/lib/sys/bld.sub
+++ b/lib/sys/bld.sub
@@ -7,6 +7,7 @@
sys+osx-x64.myr
sys+openbsd-x64.myr
sys+openbsd:6.1-x64.myr
+ sys+openbsd:6.2-x64.myr
sys+plan9-x64.myr
syscall+freebsd-x64.s
--- a/lib/sys/sys+openbsd:6.2-x64.myr
+++ b/lib/sys/sys+openbsd:6.2-x64.myr
@@ -597,6 +597,10 @@
;;
+ const Futexwait : int = 1
+ const Futexwake : int = 2
+ const Futexrequeue : int = 3
+
const Sysexit : scno = 1
const Sysfork : scno = 2
const Sysread : scno = 3
--- a/lib/thread/bld.sub
+++ b/lib/thread/bld.sub
@@ -42,6 +42,7 @@
# openbsd impl of thread primitives
exit+openbsd-x64.s
spawn+openbsd.myr
+ mutex+openbsd:6.2.myr
atomic-impl+x64.s
atomic.myr
--- /dev/null
+++ b/lib/thread/mutex+openbsd:6.2.myr
@@ -1,0 +1,76 @@
+use std
+use sys
+
+use "atomic"
+use "common"
+
+pkg thread =
+ type mutex = struct
+ _state : uint32
+ ;;
+
+ const mkmtx : (-> mutex)
+ const mtxlock : (mtx : mutex# -> void)
+ const mtxtrylock : (mtx : mutex# -> bool)
+ const mtxunlock : (mtx : mutex# -> void)
+
+ pkglocal const Unlocked : uint32 = 0
+ pkglocal const Locked : uint32 = 1
+ pkglocal const Contended : uint32 = 2
+;;
+
+var nspin = 10 /* FIXME: pick a sane number, based on CPU count */
+
+const mkmtx = {
+ -> [._state = Unlocked]
+}
+
+const mtxlock = {mtx
+ var c
+
+ /*
+ Uncontended case: we get an unlocked mutex, and we lock it.
+ */
+ c = Locked
+ for var i = 0; i < nspin; i++
+ c = xcas(&mtx._state, Unlocked, Locked)
+ if c == Unlocked
+ -> void
+ ;;
+ ;;
+
+ /*
+ Contended case: we set the lock state to Contended. This indicates that there
+ the lock is locked, and we potentially have threads waiting on it, which means
+ that we will need to wake them up.
+ */
+ if c == Locked
+ c = xchg(&mtx._state, Contended)
+ ;;
+
+ while c != Unlocked
+ sys.futex(&mtx._state, sys.Futexwait, (Contended : int), Zptr, Zptr)
+ c = xchg(&mtx._state, Contended)
+ ;;
+}
+
+const mtxtrylock = {mtx
+ -> xcas(&mtx._state, Unlocked, Locked) == Unlocked
+}
+
+const mtxunlock = {mtx
+ /*
+ Uncontended case: If the mutex state is not contended, and we still
+ are uncontended by the xchg() call, then it's safe to simply return;
+ nobody was waiting for us.
+ */
+ if mtx._state == Contended
+ mtx._state = Unlocked
+ elif xchg(&mtx._state, Unlocked) == Locked
+ -> void
+ ;;
+
+ /* wake one thread */
+ sys.futex(&mtx._state, sys.Futexwake, 1, Zptr, Zptr)
+}
+
--- a/mk/bootstrap/bootstrap+OpenBSD-amd64.sh
+++ b/mk/bootstrap/bootstrap+OpenBSD-amd64.sh
@@ -21,9 +21,9 @@
as -g -o lib/sys/syscall.o lib/sys/syscall+openbsd-x64.s
$pwd/6/6m lib/sys/ifreq+openbsd.myr
$pwd/6/6m lib/sys/systypes.myr
- $pwd/6/6m lib/sys/sys+openbsd-x64.myr
as -g -o lib/sys/util.o lib/sys/util+posixy-x64.s
$pwd/6/6m lib/sys/syserrno+openbsd.myr
+ $pwd/6/6m lib/sys/sys+openbsd:6.1-x64.myr
ar -rcs lib/sys/libsys.a lib/sys/sys.o lib/sys/syserrno.o lib/sys/util.o lib/sys/systypes.o lib/sys/ifreq.o lib/sys/syscall.o
$pwd/muse/muse -o lib/sys/libsys.use -p sys lib/sys/sys.use lib/sys/syserrno.use lib/sys/systypes.use lib/sys/ifreq.use
$pwd/6/6m -I . -I lib/sys lib/std/errno.myr
--- a/support/syscall-gen/types+openbsd:6.2-x64.frag
+++ b/support/syscall-gen/types+openbsd:6.2-x64.frag
@@ -17,10 +17,15 @@
type filemode = uint32
type filetype = uint8
type fcntlcmd = int64
-type signo = int32
+ype signo = int32
type sigflags = int32
type sigset = uint32
type msg = void
+
+const Futexwait : int = 1
+const Futexwake : int = 2
+const Futexrequeue : int = 3
+
type clock = union
`Clockrealtime