summaryrefslogtreecommitdiff
path: root/lib/thread/futex+freebsd.myr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/thread/futex+freebsd.myr')
-rw-r--r--lib/thread/futex+freebsd.myr56
1 files changed, 38 insertions, 18 deletions
diff --git a/lib/thread/futex+freebsd.myr b/lib/thread/futex+freebsd.myr
index ea5f28d..c011bf9 100644
--- a/lib/thread/futex+freebsd.myr
+++ b/lib/thread/futex+freebsd.myr
@@ -1,3 +1,4 @@
+use std
use sys
use "atomic"
@@ -7,34 +8,53 @@ pkg thread =
type ftxtag = uint32
impl atomic ftxtag
- const ftxwait : (uaddr : ftxtag#, val : ftxtag, timeout : sys.timespec# -> int)
- const ftxwake : (uaddr : ftxtag# -> int)
- const ftxwakeall : (uaddr : ftxtag# -> int)
+ const ftxwait : (uaddr : ftxtag#, val : ftxtag, tmout : std.time -> sys.errno)
+ const ftxwake : (uaddr : ftxtag# -> void)
+ const ftxwakeall : (uaddr : ftxtag# -> void)
;;
-const ftxwait = {uaddr, val, timeout
- if timeout == Zptr
- -> sys.umtx_op((uaddr : void#), sys.Umtxwaituintpriv, (val : uint64), Zptr, Zptr)
+const ftxwait = {uaddr, val, tmout
+ var ut : sys.umtx_time, utp, utsize, rc
+
+ if tmout < 0
+ utp = Zptr
+ utsize = Zptr
+ else
+ var t = (tmout : int64)
+ std.assert(sys.clock_gettime(`sys.Clockmonotonic, &ut.timeout) == 0,
+ "error: clock_gettime returned -1\n")
+ ut.timeout.nsec += (t % 1_000_000) * 1000
+ ut.timeout.sec += (ut.timeout.nsec / 1_000_000_000) + (t / 1_000_000)
+ ut.timeout.nsec %= 1_000_000_000
+ ut.flags = (sys.Umtxabstime : uint32)
+ ut.clockid = (sys.clockid(`sys.Clockmonotonic) : uint32)
+ utp = (&ut : void#)
+ utsize = (sizeof(sys.umtx_time) : void#)
+ ;;
+
+ while (rc = (sys.umtx_op((uaddr : void#),
+ sys.Umtxwaituintpriv,
+ (val : uint64),
+ utsize,
+ utp) : sys.errno)) == sys.Eintr
;;
- var ut : sys._umtx_time = [
- ._timeout = timeout#,
- ._flags = (sys.Umtxabstime : uint32),
- ._clockid = 1, /* CLOCK_MONOTONIC. Not exported from sys. */
- ]
- -> sys.umtx_op((uaddr : void#),
- sys.Umtxwaituintpriv,
- (val : uint64),
- (sizeof(sys._umtx_time) : void#),
- (&ut : void#))
+ match rc
+ | 0: -> 0
+ | sys.Eagain: -> sys.Eagain
+ | sys.Etimedout: -> sys.Etimedout
+ | err:
+ std.fput(2, "error: umtx_op returned {}\n", err)
+ std.suicide()
+ ;;
}
const ftxwake = {uaddr
- -> sys.umtx_op((uaddr : void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
+ sys.umtx_op((uaddr : void#), sys.Umtxwakepriv, 1, Zptr, Zptr)
}
const ftxwakeall = {uaddr
- -> sys.umtx_op((uaddr : void#), sys.Umtxwakepriv, 0x7fffffff, Zptr, Zptr)
+ sys.umtx_op((uaddr : void#), sys.Umtxwakepriv, 0x7fffffff, Zptr, Zptr)
}
impl atomic ftxtag =