mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-30 06:48:22 +00:00
ke: add continuations
This commit is contained in:
+46
-9
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user