shithub: mc

Download patch

ref: 61fc99f4d1bb75a6ac88cf5395f37f735589b4ce
parent: 466e33d95d9da9d218952c836d99c75ac2142b05
author: Ori Bernstein <[email protected]>
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