| author | |
| committer | |
| log | bd6acbf7da55a2497fcfb9c589093612a3fe9680 |
| tree | 6305654f8efc3c44c4afec344ff09f5fda74113d |
| parent | 6ece10f63d91cfa16d8388f8d696368537c1662e |
mainly avoid an unnecessary `@ptrCast`2 files changed, 19 insertions(+), 20 deletions(-)
lib/std/Io.zig+13-7| ... | ... | @@ -1314,17 +1314,21 @@ pub fn futexWait(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, e |
| 1314 | 1314 | /// wakeups are possible. It remains the caller's responsibility to differentiate between these |
| 1315 | 1315 | /// three possible wake-up reasons if necessary. |
| 1316 | 1316 | pub fn futexWaitTimeout(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, expected: T, timeout: Timeout) Cancelable!void { |
| 1317 | comptime assert(@sizeOf(T) == 4); | |
| 1318 | const expected_raw: *align(1) const u32 = @ptrCast(&expected); | |
| 1319 | return io.vtable.futexWait(io.userdata, @ptrCast(ptr), expected_raw.*, timeout); | |
| 1317 | const expected_int: u32 = switch (@typeInfo(T)) { | |
| 1318 | .@"enum" => @bitCast(@intFromEnum(expected)), | |
| 1319 | else => @bitCast(expected), | |
| 1320 | }; | |
| 1321 | return io.vtable.futexWait(io.userdata, @ptrCast(ptr), expected_int, timeout); | |
| 1320 | 1322 | } |
| 1321 | 1323 | /// Same as `futexWait`, except does not introduce a cancelation point. |
| 1322 | 1324 | /// |
| 1323 | 1325 | /// For a description of cancelation and cancelation points, see `Future.cancel`. |
| 1324 | 1326 | pub fn futexWaitUncancelable(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, expected: T) void { |
| 1325 | comptime assert(@sizeOf(T) == @sizeOf(u32)); | |
| 1326 | const expected_raw: *align(1) const u32 = @ptrCast(&expected); | |
| 1327 | io.vtable.futexWaitUncancelable(io.userdata, @ptrCast(ptr), expected_raw.*); | |
| 1327 | const expected_int: u32 = switch (@typeInfo(T)) { | |
| 1328 | .@"enum" => @bitCast(@intFromEnum(expected)), | |
| 1329 | else => @bitCast(expected), | |
| 1330 | }; | |
| 1331 | io.vtable.futexWaitUncancelable(io.userdata, @ptrCast(ptr), expected_int); | |
| 1328 | 1332 | } |
| 1329 | 1333 | /// Unblocks pending futex waits on `ptr`, up to a limit of `max_waiters` calls. |
| 1330 | 1334 | pub fn futexWake(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, max_waiters: u32) void { |
| ... | ... | @@ -1576,10 +1580,12 @@ pub const Event = enum(u32) { |
| 1576 | 1580 | } |
| 1577 | 1581 | } |
| 1578 | 1582 | |
| 1583 | pub const WaitTimeoutError = error{Timeout} || Cancelable; | |
| 1584 | ||
| 1579 | 1585 | /// Blocks the calling thread until either the logical boolean is set, the timeout expires, or a |
| 1580 | 1586 | /// spurious wakeup occurs. If the timeout expires or a spurious wakeup occurs, `error.Timeout` |
| 1581 | 1587 | /// is returned. |
| 1582 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) (error{Timeout} || Cancelable)!void { | |
| 1588 | pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void { | |
| 1583 | 1589 | if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) { |
| 1584 | 1590 | .unset => unreachable, |
| 1585 | 1591 | .waiting => assert(!builtin.single_threaded), // invalid state |
lib/std/Io/Threaded.zig+6-13| ... | ... | @@ -292,7 +292,7 @@ const Thread = struct { |
| 292 | 292 | .INTR => {}, // caller's responsibility to retry |
| 293 | 293 | .AGAIN => {}, // ptr.* != expect |
| 294 | 294 | .INVAL => {}, // possibly timeout overflow |
| 295 | .TIMEDOUT => {}, // timeout | |
| 295 | .TIMEDOUT => {}, | |
| 296 | 296 | .FAULT => recoverableOsBugDetected(), // ptr was invalid |
| 297 | 297 | else => recoverableOsBugDetected(), |
| 298 | 298 | } |
| ... | ... | @@ -1548,6 +1548,7 @@ fn cancel( |
| 1548 | 1548 | } |
| 1549 | 1549 | |
| 1550 | 1550 | fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.Timeout) Io.Cancelable!void { |
| 1551 | if (builtin.single_threaded) unreachable; // Deadlock. | |
| 1551 | 1552 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1552 | 1553 | const current_thread = Thread.getCurrent(t); |
| 1553 | 1554 | const t_io = ioBasic(t); |
| ... | ... | @@ -1555,29 +1556,21 @@ fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io. |
| 1555 | 1556 | const d = (timeout.toDurationFromNow(t_io) catch break :ns 10) orelse break :ns null; |
| 1556 | 1557 | break :ns std.math.lossyCast(u64, d.raw.toNanoseconds()); |
| 1557 | 1558 | }; |
| 1558 | switch (native_os) { | |
| 1559 | .illumos, .netbsd, .openbsd => @panic("TODO"), | |
| 1560 | else => try current_thread.futexWaitTimed(ptr, expected, timeout_ns), | |
| 1561 | } | |
| 1559 | return Thread.futexWaitTimed(current_thread, ptr, expected, timeout_ns); | |
| 1562 | 1560 | } |
| 1563 | 1561 | |
| 1564 | 1562 | fn futexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void { |
| 1563 | if (builtin.single_threaded) unreachable; // Deadlock. | |
| 1565 | 1564 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1566 | 1565 | _ = t; |
| 1567 | switch (native_os) { | |
| 1568 | .illumos, .netbsd, .openbsd => @panic("TODO"), | |
| 1569 | else => Thread.futexWaitUncancelable(ptr, expected), | |
| 1570 | } | |
| 1566 | Thread.futexWaitUncancelable(ptr, expected); | |
| 1571 | 1567 | } |
| 1572 | 1568 | |
| 1573 | 1569 | fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void { |
| 1574 | 1570 | if (builtin.single_threaded) unreachable; // Nothing to wake up. |
| 1575 | 1571 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1576 | 1572 | _ = t; |
| 1577 | switch (native_os) { | |
| 1578 | .illumos, .netbsd, .openbsd => @panic("TODO"), | |
| 1579 | else => Thread.futexWake(ptr, max_waiters), | |
| 1580 | } | |
| 1573 | Thread.futexWake(ptr, max_waiters); | |
| 1581 | 1574 | } |
| 1582 | 1575 | |
| 1583 | 1576 | const dirCreateDir = switch (native_os) { |