diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 9c3645616327412f8b3b0455ca604bde65c44b7d..2c2307315727337ae178581499b0008403f13c4b 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -417,6 +417,25 @@ const Thread = struct { else => unreachable, }; }, + .dragonfly => { + var timeout_us: c_int = undefined; + if (timeout_ns) |ns| { + timeout_us = std.math.cast(c_int, ns / std.time.ns_per_us) orelse std.math.maxInt(c_int); + } else { + timeout_us = 0; + } + if (thread) |t| try t.beginSyscall(); + const rc = std.c.umtx_sleep(@ptrCast(ptr), @bitCast(expect), timeout_us); + if (thread) |t| t.endSyscall(); + if (is_debug) switch (std.posix.errno(rc)) { + .SUCCESS => {}, + .BUSY => {}, // ptr != expect + .AGAIN => {}, // maybe timed out, or paged out, or hit 2s kernel refresh + .INTR => {}, // spurious wake + .INVAL => unreachable, // invalid timeout + else => unreachable, + }; + }, else => if (std.Thread.use_pthreads) { // TODO integrate the following function being called with robust cancelation. return pthreads_futex.wait(ptr, expect, timeout_ns) catch |err| switch (err) { @@ -510,6 +529,13 @@ const Thread = struct { ); assert(rc >= 0); }, + .dragonfly => { + // will generally return 0 unless the address is bad + _ = std.c.umtx_wakeup( + @ptrCast(ptr), + @min(max_waiters, std.math.maxInt(c_int)), + ); + }, else => if (std.Thread.use_pthreads) { return pthreads_futex.wake(ptr, max_waiters); } else {