ke/wait: make timeout parameter explicit

This commit is contained in:
Loïc Grégoire
2026-08-01 22:44:22 -04:00
parent 02d2fb5144
commit 05c7694776
11 changed files with 27 additions and 19 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ fn drain_from_all(seq: usize) usize {
fn worker(_: ?*anyopaque) void { fn worker(_: ?*anyopaque) void {
while (true) { while (true) {
_ = ke.wait.wait_one(&ke.log.event.hdr, null) catch unreachable; _ = ke.wait.wait_one(&ke.log.event.hdr, .{}) catch unreachable;
ke.log.event.reset(); ke.log.event.reset();
last_seq = drain_from_all(last_seq); last_seq = drain_from_all(last_seq);
+1 -1
View File
@@ -257,7 +257,7 @@ pub fn enqueue(item: *WorkItem) void {
fn pool_manager(_: ?*anyopaque) void { fn pool_manager(_: ?*anyopaque) void {
while (true) { while (true) {
_ = ke.wait.wait_one(&pool_manager_event.hdr, null) catch unreachable; _ = ke.wait.wait_one(&pool_manager_event.hdr, .{}) catch unreachable;
// We have been signaled, go through every pool and grow it if needed. // We have been signaled, go through every pool and grow it if needed.
// Failure to grow is ignored, it is only a latency problem and should be fixed // Failure to grow is ignored, it is only a latency problem and should be fixed
+1 -1
View File
@@ -75,7 +75,7 @@ pub const Queue = struct {
self.hdr.lock.release(ipl); self.hdr.lock.release(ipl);
// Wait until the queue has something for us. // Wait until the queue has something for us.
_ = try ke.wait.wait_one(&self.hdr, timeout); _ = try ke.wait.wait_one(&self.hdr, .{ .timeout = timeout });
// Grab the queue item and set it to null. // Grab the queue item and set it to null.
const ret = td.queue_item orelse unreachable; const ret = td.queue_item orelse unreachable;
+1 -1
View File
@@ -441,7 +441,7 @@ pub fn block(turnstile: ?*Turnstile, obj: *anyopaque, own: Ownership, queue: Que
// Now block on the event. // Now block on the event.
_ = ke.ipl.lower(.Passive); _ = ke.ipl.lower(.Passive);
_ = ke.wait.wait_one(&waiter.event.hdr, null) catch unreachable; _ = ke.wait.wait_one(&waiter.event.hdr, .{}) catch unreachable;
_ = ke.ipl.raise(ipl); _ = ke.ipl.raise(ipl);
} }
+17 -9
View File
@@ -97,24 +97,32 @@ pub const Status = enum(u8) {
Satisfied, Satisfied,
}; };
const Options = struct {
timeout: ?r.Nanoseconds = null,
waitblocks: ?[*]WaitBlock = null,
};
/// Wait for the provided object to be signaled. /// Wait for the provided object to be signaled.
pub fn wait_one(object: *DispatchHeader, timeout: ?r.Nanoseconds) !usize { /// This will only return an error if `timeout` is provided and
/// the wait times out.
pub fn wait_one(object: *DispatchHeader, opts: Options) !usize {
var objects = [_]*DispatchHeader{object}; var objects = [_]*DispatchHeader{object};
return wait_any(&objects, timeout, null); return wait_any(&objects, opts);
} }
/// Wait for any of the provided objects to be signaled. /// Wait for any of the provided objects to be signaled.
/// Returns the index of the object that was signaled, or an error. /// Returns the index of the object that was signaled, or an error
/// in the case of timeout.
/// If `timeout` is not provided, it will wait indefinitely. /// If `timeout` is not provided, it will wait indefinitely.
/// If `waitblocks` is specified, then the wait will use those waitblocks for the operation. /// If `waitblocks` is specified, then the wait will use those waitblocks for the operation.
/// Note that if `timeout` is provided, then one additional waitblock must be allocated. /// Note that if `timeout` is provided, then one additional waitblock must be allocated.
pub fn wait_any(objects: []*DispatchHeader, timeout: ?r.Nanoseconds, waitblocks: ?[*]WaitBlock) !usize { pub fn wait_any(objects: []*DispatchHeader, opts: Options) !usize {
const ipl = ke.ipl.raise(.Dispatch); const ipl = ke.ipl.raise(.Dispatch);
defer ke.ipl.lower(ipl); defer ke.ipl.lower(ipl);
const curtd = ki.sched.percpu.local().current_thread.?; const curtd = ki.sched.percpu.local().current_thread.?;
const obj_count = objects.len; const obj_count = objects.len;
const has_timeout = timeout != null; const has_timeout = opts.timeout != null;
const blocks = waitblocks orelse blk: { const blocks = opts.waitblocks orelse blk: {
std.debug.assert(obj_count <= curtd.waitblocks.len - @intFromBool(has_timeout)); std.debug.assert(obj_count <= curtd.waitblocks.len - @intFromBool(has_timeout));
break :blk &curtd.waitblocks; break :blk &curtd.waitblocks;
}; };
@@ -158,7 +166,7 @@ pub fn wait_any(objects: []*DispatchHeader, timeout: ?r.Nanoseconds, waitblocks:
} }
// Wait was already satisfied, back out. // Wait was already satisfied, back out.
if (satisfier != null or (has_timeout and timeout.? == 0)) { if (satisfier != null or (has_timeout and opts.timeout.? == 0)) {
if (satisfier != null) { if (satisfier != null) {
std.debug.assert(curtd.wait_status.load(.acquire) == .Satisfied); std.debug.assert(curtd.wait_status.load(.acquire) == .Satisfied);
} }
@@ -182,8 +190,8 @@ pub fn wait_any(objects: []*DispatchHeader, timeout: ?r.Nanoseconds, waitblocks:
return satisfier orelse error.Timeout; return satisfier orelse error.Timeout;
} }
if (has_timeout) { if (opts.timeout) |timeout| {
ke.timer.set(timer, timeout.?, null); ke.timer.set(timer, timeout, .{});
} }
curtd.lock.acquire_no_ipl(); curtd.lock.acquire_no_ipl();
+1 -1
View File
@@ -47,7 +47,7 @@ fn wait_for_pages(old_ipl: ke.Ipl) void {
list_lock.release(ipl); list_lock.release(ipl);
_ = ke.wait.wait_one(&free_page_event.hdr, null) catch unreachable; _ = ke.wait.wait_one(&free_page_event.hdr, .{}) catch unreachable;
ipl = list_lock.acquire(); ipl = list_lock.acquire();
cnt = free_pages; cnt = free_pages;
+1 -1
View File
@@ -101,7 +101,7 @@ fn perform_delay(ms: usize) void {
var timer: ke.Timer = undefined; var timer: ke.Timer = undefined;
timer.init(); timer.init();
ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); ke.timer.set(&timer, std.time.ns_per_ms * ms, .{});
_ = ke.wait.wait_one(&timer.hdr, null) catch unreachable; _ = ke.wait.wait_one(&timer.hdr, .{}) catch unreachable;
} }
fn particle(param: ?*anyopaque) void { fn particle(param: ?*anyopaque) void {
+1 -1
View File
@@ -35,7 +35,7 @@ fn delay_ms(ms: usize) void {
var timer: ke.Timer = undefined; var timer: ke.Timer = undefined;
timer.init(); timer.init();
ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); ke.timer.set(&timer, std.time.ns_per_ms * ms, .{});
_ = ke.wait.wait_one(&timer.hdr, null) catch unreachable; _ = ke.wait.wait_one(&timer.hdr, .{}) catch unreachable;
} }
fn worker(param: ?*anyopaque) void { fn worker(param: ?*anyopaque) void {
+1 -1
View File
@@ -42,7 +42,7 @@ fn delay_ms(ms: usize) void {
var timer: ke.Timer = undefined; var timer: ke.Timer = undefined;
timer.init(); timer.init();
ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); ke.timer.set(&timer, std.time.ns_per_ms * ms, .{});
_ = ke.wait.wait_one(&timer.hdr, null) catch unreachable; _ = ke.wait.wait_one(&timer.hdr, .{}) catch unreachable;
} }
fn reader(param: ?*anyopaque) void { fn reader(param: ?*anyopaque) void {
+1 -1
View File
@@ -64,7 +64,7 @@ fn delay_ms(ms: usize) void {
var timer: ke.Timer = undefined; var timer: ke.Timer = undefined;
timer.init(); timer.init();
ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); ke.timer.set(&timer, std.time.ns_per_ms * ms, .{});
_ = ke.wait.wait_one(&timer.hdr, null) catch unreachable; _ = ke.wait.wait_one(&timer.hdr, .{}) catch unreachable;
} }
/// Park here while the checker is verifying quiescence. Only ever called /// Park here while the checker is verifying quiescence. Only ever called
+1 -1
View File
@@ -46,7 +46,7 @@ fn delay_ms(ms: usize) void {
var timer: ke.Timer = undefined; var timer: ke.Timer = undefined;
timer.init(); timer.init();
ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); ke.timer.set(&timer, std.time.ns_per_ms * ms, .{});
_ = ke.wait.wait_one(&timer.hdr, null) catch unreachable; _ = ke.wait.wait_one(&timer.hdr, .{}) catch unreachable;
} }
fn wait_flag(flag: *std.atomic.Value(bool)) void { fn wait_flag(flag: *std.atomic.Value(bool)) void {