shithub: mc

Download patch

ref: 93cff6aba077499c3693896cba43b1ceaaca7a62
parent: d2a89e73c70057b57f3ad7e158645744df1f29b1
author: iriri <[email protected]>
date: Sat Aug 11 15:15:59 EDT 2018

Only attempt to ftxwake in sempost if there might be a waiter.

--- a/lib/thread/sem+futex.myr
+++ b/lib/thread/sem+futex.myr
@@ -5,13 +5,14 @@
 
 pkg thread =
 	type sem = struct
-		_val : ftxtag
+		_val      : ftxtag
+		_nwaiters : uint32
 	;;
 
-	const mksem : (v : uint32 -> sem)
-	const semwait : (s : sem# -> void)
+	const mksem      : (v : uint32 -> sem)
+	const semwait    : (s : sem# -> void)
 	const semtrywait : (s : sem# -> bool)
-	const sempost : (s : sem# -> void)
+	const sempost    : (s : sem# -> void)
 ;;
 
 const mksem = {v
@@ -21,9 +22,11 @@
 const semwait = {s
 	var v = 0
 
+	xadd(&s._nwaiters, 1)
 	for ; ;
 		while (v = s._val) > 0
 			if xcas(&s._val, v, v - 1) == v
+				xadd(&s._nwaiters, -1)
 				-> void
 			;;
 		;;
@@ -47,6 +50,7 @@
 const sempost = {s
 	std.assert((xadd(&s._val, 1) : uint32) != ~0x0, "error: semaphore overflowed\n")
 
-	/* Unconditionally wake one waiter */
-	ftxwake(&s._val)
+	if xget(&s._nwaiters) > 0
+		ftxwake(&s._val)
+	;;
 }