diff --git a/src/ex/console.zig b/src/ex/console.zig index 665a277..8dcc739 100644 --- a/src/ex/console.zig +++ b/src/ex/console.zig @@ -87,7 +87,7 @@ fn drain_from_all(seq: usize) usize { fn worker(_: ?*anyopaque) void { 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(); last_seq = drain_from_all(last_seq); diff --git a/src/ex/work.zig b/src/ex/work.zig index ba3c0d3..b6c9f99 100644 --- a/src/ex/work.zig +++ b/src/ex/work.zig @@ -257,7 +257,7 @@ pub fn enqueue(item: *WorkItem) void { fn pool_manager(_: ?*anyopaque) void { 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. // Failure to grow is ignored, it is only a latency problem and should be fixed diff --git a/src/kern/queue.zig b/src/kern/queue.zig index 392c6bf..1360cd5 100644 --- a/src/kern/queue.zig +++ b/src/kern/queue.zig @@ -75,7 +75,7 @@ pub const Queue = struct { self.hdr.lock.release(ipl); // 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. const ret = td.queue_item orelse unreachable; diff --git a/src/kern/turnstile.zig b/src/kern/turnstile.zig index c5851a9..1ab86cb 100644 --- a/src/kern/turnstile.zig +++ b/src/kern/turnstile.zig @@ -441,7 +441,7 @@ pub fn block(turnstile: ?*Turnstile, obj: *anyopaque, own: Ownership, queue: Que // Now block on the event. _ = 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); } diff --git a/src/kern/wait.zig b/src/kern/wait.zig index 68bf3ea..0a6a3b8 100644 --- a/src/kern/wait.zig +++ b/src/kern/wait.zig @@ -97,24 +97,32 @@ pub const Status = enum(u8) { Satisfied, }; +const Options = struct { + timeout: ?r.Nanoseconds = null, + waitblocks: ?[*]WaitBlock = null, +}; + /// 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}; - return wait_any(&objects, timeout, null); + return wait_any(&objects, opts); } /// 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 `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. -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); defer ke.ipl.lower(ipl); const curtd = ki.sched.percpu.local().current_thread.?; const obj_count = objects.len; - const has_timeout = timeout != null; - const blocks = waitblocks orelse blk: { + const has_timeout = opts.timeout != null; + const blocks = opts.waitblocks orelse blk: { std.debug.assert(obj_count <= curtd.waitblocks.len - @intFromBool(has_timeout)); break :blk &curtd.waitblocks; }; @@ -158,7 +166,7 @@ pub fn wait_any(objects: []*DispatchHeader, timeout: ?r.Nanoseconds, waitblocks: } // 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) { 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; } - if (has_timeout) { - ke.timer.set(timer, timeout.?, null); + if (opts.timeout) |timeout| { + ke.timer.set(timer, timeout, .{}); } curtd.lock.acquire_no_ipl(); diff --git a/src/mm/phys.zig b/src/mm/phys.zig index bdecffc..ef4937a 100644 --- a/src/mm/phys.zig +++ b/src/mm/phys.zig @@ -47,7 +47,7 @@ fn wait_for_pages(old_ipl: ke.Ipl) void { 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(); cnt = free_pages; diff --git a/src/tests/fireworks.zig b/src/tests/fireworks.zig index 697cabe..f4bdc9e 100644 --- a/src/tests/fireworks.zig +++ b/src/tests/fireworks.zig @@ -101,7 +101,7 @@ fn perform_delay(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); 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 { diff --git a/src/tests/mutex.zig b/src/tests/mutex.zig index 1611326..c424e76 100644 --- a/src/tests/mutex.zig +++ b/src/tests/mutex.zig @@ -35,7 +35,7 @@ fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); 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 { diff --git a/src/tests/smr.zig b/src/tests/smr.zig index 138eb20..f33ccc0 100644 --- a/src/tests/smr.zig +++ b/src/tests/smr.zig @@ -42,7 +42,7 @@ fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); 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 { diff --git a/src/tests/smr_pi.zig b/src/tests/smr_pi.zig index 47ce7a6..3543d2a 100644 --- a/src/tests/smr_pi.zig +++ b/src/tests/smr_pi.zig @@ -64,7 +64,7 @@ fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); 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 diff --git a/src/tests/turnstile.zig b/src/tests/turnstile.zig index 01509d7..3d02f94 100644 --- a/src/tests/turnstile.zig +++ b/src/tests/turnstile.zig @@ -46,7 +46,7 @@ fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); 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 {