summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoririri <iri@konnichiwastevenspielbergde.su>2018-08-11 19:15:59 -0700
committerOri Bernstein <ori@eigenstate.org>2018-08-19 21:02:20 -0700
commit93cff6aba077499c3693896cba43b1ceaaca7a62 (patch)
tree4524b645b810f164951a22d09822432cca99b74f
parentd2a89e73c70057b57f3ad7e158645744df1f29b1 (diff)
downloadmc-93cff6aba077499c3693896cba43b1ceaaca7a62.tar.gz
Only attempt to ftxwake in sempost if there might be a waiter.
-rw-r--r--lib/thread/sem+futex.myr16
1 files changed, 10 insertions, 6 deletions
diff --git a/lib/thread/sem+futex.myr b/lib/thread/sem+futex.myr
index 542586b..45bca0d 100644
--- a/lib/thread/sem+futex.myr
+++ b/lib/thread/sem+futex.myr
@@ -5,13 +5,14 @@ use "futex"
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 mksem = {v
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 semtrywait = {s
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)
+ ;;
}