ex: add DelayedWorkItem

Separate WorkItem from DelayedWorkItem so that the former doesn't pay
the price of a timer and a Dpc if it won't ever get delayed.
This commit is contained in:
Loïc Grégoire
2026-08-01 09:53:17 -04:00
parent 1569bc2b29
commit 0f0ddffb2c
3 changed files with 25 additions and 7 deletions
+1
View File
@@ -3,6 +3,7 @@ pub const private = @import("private.zig");
const p = private; const p = private;
pub const WorkItem = p.work.WorkItem; pub const WorkItem = p.work.WorkItem;
pub const DelayedWorkItem = p.work.DelayedWorkItem;
pub const Console = p.console.Console; pub const Console = p.console.Console;
pub const work = struct { pub const work = struct {
+23 -6
View File
@@ -40,8 +40,6 @@ pub const WorkItem = struct {
link: rtl.List.Entry, link: rtl.List.Entry,
enqueued: std.atomic.Value(bool), enqueued: std.atomic.Value(bool),
priority: Priority, priority: Priority,
dpc: ke.Dpc,
timer: ke.Timer,
pub const Priority = enum { pub const Priority = enum {
/// Low priority background work. /// Low priority background work.
@@ -67,10 +65,29 @@ pub const WorkItem = struct {
.link = undefined, .link = undefined,
.enqueued = .init(false), .enqueued = .init(false),
.priority = priority, .priority = priority,
};
}
};
/// Represents a work item that will be enqueued in a given amount of time.
pub const DelayedWorkItem = struct {
item: WorkItem,
dpc: ke.Dpc,
timer: ke.Timer,
pub fn init(
self: *DelayedWorkItem,
priority: WorkItem.Priority,
func: *const fn (arg: ?*anyopaque) void,
arg: ?*anyopaque,
) void {
self.* = .{
.item = undefined,
.dpc = .init(work_dpc), .dpc = .init(work_dpc),
.timer = undefined, .timer = undefined,
}; };
self.item.init(priority, func, arg);
self.timer.init(); self.timer.init();
} }
}; };
@@ -196,14 +213,14 @@ fn work_loop(p: ?*anyopaque) void {
} }
} }
/// Called when a work timer expires. /// Called when a delayed work timer expires.
fn work_dpc(dpc: *ke.Dpc, _: ?*anyopaque) void { fn work_dpc(dpc: *ke.Dpc, _: ?*anyopaque) void {
const item: *WorkItem = @fieldParentPtr("dpc", dpc); const item: *DelayedWorkItem = @fieldParentPtr("dpc", dpc);
enqueue(item); enqueue(&item.item);
} }
/// Enqueue a work item in `time`. /// Enqueue a work item in `time`.
pub fn enqueue_in(item: *WorkItem, time: r.Nanoseconds) void { pub fn enqueue_in(item: *DelayedWorkItem, time: r.Nanoseconds) void {
ke.timer.set(&item.timer, time, &item.dpc); ke.timer.set(&item.timer, time, &item.dpc);
} }
+1 -1
View File
@@ -119,7 +119,7 @@ const mi = mm.private;
/// Interval at which we do housekeeping (working set update, reaping, etc.) /// Interval at which we do housekeeping (working set update, reaping, etc.)
const update_interval_s = 15; const update_interval_s = 15;
const update_interval = std.time.ns_per_s * update_interval_s; const update_interval = std.time.ns_per_s * update_interval_s;
var update_work_item: ex.WorkItem = undefined; var update_work_item: ex.DelayedWorkItem = undefined;
/// Fixed point conversion for WMA computation. /// Fixed point conversion for WMA computation.
const wma_unit = 256; const wma_unit = 256;