summaryrefslogtreecommitdiff
path: root/lib/thread/condvar.myr
diff options
context:
space:
mode:
authoririri <iri@konnichiwastevenspielbergde.su>2018-08-18 16:17:42 -0700
committerOri Bernstein <ori@eigenstate.org>2018-08-19 18:07:14 -0700
commit2fca1caa1935baf0473efc367e24dab57c52517d (patch)
tree5cd9aed3925ff4de81884a357b834bb5330a88a3 /lib/thread/condvar.myr
parent0bb2378d7e2b714998b34394f6977b2ead023d6c (diff)
downloadmc-2fca1caa1935baf0473efc367e24dab57c52517d.tar.gz
Fix futex timeouts and handle futex error codes.
Diffstat (limited to 'lib/thread/condvar.myr')
-rw-r--r--lib/thread/condvar.myr36
1 files changed, 13 insertions, 23 deletions
diff --git a/lib/thread/condvar.myr b/lib/thread/condvar.myr
index 4fde707..f843f84 100644
--- a/lib/thread/condvar.myr
+++ b/lib/thread/condvar.myr
@@ -8,7 +8,8 @@ use "sem"
pkg thread =
type cond = struct
_mtx : mutex#
- _waitq : condwaiter#
+ _head : condwaiter#
+ _tail : condwaiter#
_lock : mutex
;;
@@ -18,15 +19,8 @@ pkg thread =
const condbroadcast : (cond : cond# -> void)
;;
-/*
-The waitqueue is a doubly-linked list because we'll need to remove waiters from
-anywhere in the list when we add timeout support.
-
-`cond._waitq.prev` is the tail of the queue.
-*/
type condwaiter = struct
next : condwaiter#
- prev : condwaiter#
sem : sem
;;
@@ -40,14 +34,9 @@ const condwait = {cond
var waiter = std.mk([.sem = mksem(0)])
mtxlock(lock)
- match cond._waitq
- | Zptr:
- waiter.prev = waiter
- cond._waitq = waiter
- | q:
- waiter.prev = q.prev
- waiter.prev.next = waiter
- q.prev = waiter
+ match cond._tail
+ | Zptr: cond._head = cond._tail = waiter
+ | tail: cond._tail = tail.next = waiter
;;
mtxunlock(lock)
@@ -61,13 +50,13 @@ const condsignal = {cond
var lock = &cond._lock
mtxlock(lock)
- var head = cond._waitq
+ var head = cond._head
if head != Zptr
- if head.next != Zptr
- head.next.prev = head.prev
- ;;
- cond._waitq = head.next
+ cond._head = head.next
sempost(&head.sem)
+ if cond._head == Zptr
+ cond._tail = Zptr
+ ;;
;;
mtxunlock(lock)
}
@@ -81,9 +70,10 @@ const condbroadcast = {cond
var head = Zptr
mtxlock(lock)
- while (head = cond._waitq) != Zptr
- cond._waitq = head.next
+ while (head = cond._head) != Zptr
+ cond._head = head.next
sempost(&head.sem)
;;
+ cond._tail = Zptr
mtxunlock(lock)
}