ke: add continuations

This commit is contained in:
Loïc Grégoire
2026-08-29 20:03:22 -04:00
parent d06351f31c
commit 8226a205a0
20 changed files with 735 additions and 194 deletions
+46 -9
View File
@@ -8,9 +8,10 @@ const ke = r.ke;
const ki = ke.private;
const mm = r.mm;
const kernel_thread_stack_size = r.kib(16);
pub const kernel_thread_stack_size = r.kib(16);
var reaper_item: ex.WorkItem = undefined;
var stack_item: ex.WorkItem = undefined;
var thread_zone: mm.zone.TypedZone(Thread) = undefined;
/// Higher-level wrapper over a thread.
@@ -33,7 +34,6 @@ fn reap_thread(obj: *anyopaque, _: ?*anyopaque) void {
const td: *Thread = @fieldParentPtr("kern", ketd);
psp.turnstile_zone.destroy(td.kern.turnstile);
mm.heap.free(td.kern.stack, kernel_thread_stack_size);
thread_zone.destroy(td);
}
@@ -41,14 +41,19 @@ fn reaper_fn(_: ?*anyopaque) void {
ke.thread.reaper_list.process(reap_thread, null);
}
fn activation(_: *rtl.HandoffList) void {
fn reaper_activation(_: *rtl.HandoffList) void {
ex.work.enqueue(&reaper_item);
}
pub fn stack_activation() void {
ex.work.enqueue(&stack_item);
}
pub fn init() void {
thread_zone.init("thread", .{});
ke.thread.reaper_list.* = .init(activation);
ke.thread.reaper_list.* = .init(reaper_activation);
reaper_item.init(.High, reaper_fn, null);
stack_item.init(.High, stack_fn, null);
}
/// Create a kernel thread.
@@ -57,14 +62,25 @@ pub fn init() void {
/// - `arg`: argument passed to `entry`.
pub fn create_kernel(
prio: ke.Priority,
entry: *const fn (arg: ?*anyopaque) void,
arg: ?*anyopaque,
continuation: ke.Continuation,
start_with_stack: bool,
) !*Thread {
var td = try thread_zone.create();
const stack = try mm.heap.alloc(kernel_thread_stack_size, .WaitForMemory);
td.kern.init(@intFromPtr(stack), kernel_thread_stack_size, prio, entry, arg);
td.kern.turnstile = try psp.turnstile_zone.create();
const stack = if (start_with_stack)
@intFromPtr(try mm.heap.alloc(kernel_thread_stack_size, .WaitForMemory)) +
kernel_thread_stack_size
else
0;
const turnstile = try psp.turnstile_zone.create();
td.kern.init(.{
.stack = stack,
.turnstile = turnstile,
.entry = continuation,
.priority = prio,
});
return td;
}
@@ -74,3 +90,24 @@ pub fn create_kernel(
pub fn exit() void {
ke.thread.exit();
}
fn allocate_stack(obj: *anyopaque, _: ?*anyopaque) void {
const link: **rtl.List.Entry = @ptrCast(@alignCast(obj));
// Bleh
const entry: *rtl.List.Entry = @fieldParentPtr("next", link);
const thread: *ke.Thread = @fieldParentPtr("runq_link", entry);
const stack = mm.heap.alloc(kernel_thread_stack_size, .WaitForMemory) catch
unreachable;
const stack_top = @intFromPtr(stack) + kernel_thread_stack_size;
thread.context.reset(stack_top, ke.thread.call_continuation, thread);
ke.sched.enqueue(thread);
}
fn stack_fn(_: ?*anyopaque) void {
ke.thread.thread_stack_queue.process(allocate_stack, null);
}