mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:44:43 +01:00
std.Io: minor cleanups to futex and event
mainly avoid an unnecessary `@ptrCast`
This commit is contained in:
parent
6ece10f63d
commit
bd6acbf7da
2 changed files with 19 additions and 20 deletions
|
|
@ -1314,17 +1314,21 @@ pub fn futexWait(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, e
|
|||
/// wakeups are possible. It remains the caller's responsibility to differentiate between these
|
||||
/// three possible wake-up reasons if necessary.
|
||||
pub fn futexWaitTimeout(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, expected: T, timeout: Timeout) Cancelable!void {
|
||||
comptime assert(@sizeOf(T) == 4);
|
||||
const expected_raw: *align(1) const u32 = @ptrCast(&expected);
|
||||
return io.vtable.futexWait(io.userdata, @ptrCast(ptr), expected_raw.*, timeout);
|
||||
const expected_int: u32 = switch (@typeInfo(T)) {
|
||||
.@"enum" => @bitCast(@intFromEnum(expected)),
|
||||
else => @bitCast(expected),
|
||||
};
|
||||
return io.vtable.futexWait(io.userdata, @ptrCast(ptr), expected_int, timeout);
|
||||
}
|
||||
/// Same as `futexWait`, except does not introduce a cancelation point.
|
||||
///
|
||||
/// For a description of cancelation and cancelation points, see `Future.cancel`.
|
||||
pub fn futexWaitUncancelable(io: Io, comptime T: type, ptr: *align(@alignOf(u32)) const T, expected: T) void {
|
||||
comptime assert(@sizeOf(T) == @sizeOf(u32));
|
||||
const expected_raw: *align(1) const u32 = @ptrCast(&expected);
|
||||
io.vtable.futexWaitUncancelable(io.userdata, @ptrCast(ptr), expected_raw.*);
|
||||
const expected_int: u32 = switch (@typeInfo(T)) {
|
||||
.@"enum" => @bitCast(@intFromEnum(expected)),
|
||||
else => @bitCast(expected),
|
||||
};
|
||||
io.vtable.futexWaitUncancelable(io.userdata, @ptrCast(ptr), expected_int);
|
||||
}
|
||||
/// Unblocks pending futex waits on `ptr`, up to a limit of `max_waiters` calls.
|
||||
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) {
|
|||
}
|
||||
}
|
||||
|
||||
pub const WaitTimeoutError = error{Timeout} || Cancelable;
|
||||
|
||||
/// Blocks the calling thread until either the logical boolean is set, the timeout expires, or a
|
||||
/// spurious wakeup occurs. If the timeout expires or a spurious wakeup occurs, `error.Timeout`
|
||||
/// is returned.
|
||||
pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) (error{Timeout} || Cancelable)!void {
|
||||
pub fn waitTimeout(event: *Event, io: Io, timeout: Timeout) WaitTimeoutError!void {
|
||||
if (@cmpxchgStrong(Event, event, .unset, .waiting, .acquire, .acquire)) |prev| switch (prev) {
|
||||
.unset => unreachable,
|
||||
.waiting => assert(!builtin.single_threaded), // invalid state
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ const Thread = struct {
|
|||
.INTR => {}, // caller's responsibility to retry
|
||||
.AGAIN => {}, // ptr.* != expect
|
||||
.INVAL => {}, // possibly timeout overflow
|
||||
.TIMEDOUT => {}, // timeout
|
||||
.TIMEDOUT => {},
|
||||
.FAULT => recoverableOsBugDetected(), // ptr was invalid
|
||||
else => recoverableOsBugDetected(),
|
||||
}
|
||||
|
|
@ -1548,6 +1548,7 @@ fn cancel(
|
|||
}
|
||||
|
||||
fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.Timeout) Io.Cancelable!void {
|
||||
if (builtin.single_threaded) unreachable; // Deadlock.
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
const current_thread = Thread.getCurrent(t);
|
||||
const t_io = ioBasic(t);
|
||||
|
|
@ -1555,29 +1556,21 @@ fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.
|
|||
const d = (timeout.toDurationFromNow(t_io) catch break :ns 10) orelse break :ns null;
|
||||
break :ns std.math.lossyCast(u64, d.raw.toNanoseconds());
|
||||
};
|
||||
switch (native_os) {
|
||||
.illumos, .netbsd, .openbsd => @panic("TODO"),
|
||||
else => try current_thread.futexWaitTimed(ptr, expected, timeout_ns),
|
||||
}
|
||||
return Thread.futexWaitTimed(current_thread, ptr, expected, timeout_ns);
|
||||
}
|
||||
|
||||
fn futexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void {
|
||||
if (builtin.single_threaded) unreachable; // Deadlock.
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
switch (native_os) {
|
||||
.illumos, .netbsd, .openbsd => @panic("TODO"),
|
||||
else => Thread.futexWaitUncancelable(ptr, expected),
|
||||
}
|
||||
Thread.futexWaitUncancelable(ptr, expected);
|
||||
}
|
||||
|
||||
fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void {
|
||||
if (builtin.single_threaded) unreachable; // Nothing to wake up.
|
||||
const t: *Threaded = @ptrCast(@alignCast(userdata));
|
||||
_ = t;
|
||||
switch (native_os) {
|
||||
.illumos, .netbsd, .openbsd => @panic("TODO"),
|
||||
else => Thread.futexWake(ptr, max_waiters),
|
||||
}
|
||||
Thread.futexWake(ptr, max_waiters);
|
||||
}
|
||||
|
||||
const dirCreateDir = switch (native_os) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue