From e50b1e016723abb43ad0aef5abe84a2cd6621d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gr=C3=A9goire?= Date: Thu, 18 Jun 2026 18:54:38 -0400 Subject: [PATCH] ps: initial process subsystem --- src/ex/fireworks.zig | 35 ++++++--------------------------- src/ex/init.zig | 43 ++++++----------------------------------- src/kern/init.zig | 3 ++- src/kern/thread.zig | 7 ++++--- src/platform/pc/smp.zig | 4 +--- src/proc/private.zig | 28 +++++++++++++++++++++++++++ src/proc/root.zig | 16 +++++++++++++++ src/proc/thread.zig | 28 +++++++++++++++++++++++++++ src/root.zig | 1 + 9 files changed, 92 insertions(+), 73 deletions(-) create mode 100644 src/proc/private.zig create mode 100644 src/proc/root.zig create mode 100644 src/proc/thread.zig diff --git a/src/ex/fireworks.zig b/src/ex/fireworks.zig index 7287dbe..63f8648 100644 --- a/src/ex/fireworks.zig +++ b/src/ex/fireworks.zig @@ -3,6 +3,7 @@ const std = @import("std"); const r = @import("root"); const ke = r.ke; const mm = r.mm; +const ps = r.ps; const sintab = @import("sintab.zig"); var pixel_buffer: [*]u8 = undefined; @@ -30,20 +31,8 @@ fn plot_pixel(x: i64, y: i64, color: u32) void { @as(*u32, @ptrCast(@alignCast(&pixel_buffer[pixel_offset]))).* = color; } -fn read_tsc() u64 { - var lo: u32 = 0; - var hi: u32 = 0; - - asm volatile ("rdtsc" - : [lo] "={eax}" (lo), - [hi] "={edx}" (hi), - ); - - return (@as(u64, hi) << 32) | @as(u64, lo); -} - fn rand_tsc_based() u32 { - const tsc = read_tsc(); + const tsc = ke.time.read_time(); const lo: u32 = @truncate(tsc); const hi: u32 = @truncate(tsc >> 32); return lo ^ hi; @@ -163,26 +152,14 @@ fn particle(param: ?*anyopaque) void { ke.sched.block(); } -fn make_thread(entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) *ke.Thread { - var ret: *ke.Thread = mm.zone.gpa.create(ke.Thread) catch @panic("oom"); - const stack = mm.heap.alloc(r.kib(16)) catch @panic("wtf"); - - ret.init(@intFromPtr(stack), r.kib(16), entry, arg); - - ret.priority = ke.Thread.Priority.default; - ret.base_priority = ke.Thread.Priority.default; - - return ret; -} - fn spawn_particle(arg: ?*anyopaque) void { - const thread = make_thread(&particle, arg); - ke.sched.enqueue(thread); + const t = ps.thread.create_kernel(ke.Thread.Priority.default, &particle, arg) catch @panic("OOM"); + ke.sched.enqueue(&t.kern); } fn spawn_explodeable() void { - const thread = make_thread(&explodeable, null); - ke.sched.enqueue(thread); + const t = ps.thread.create_kernel(ke.Thread.Priority.default, &explodeable, null) catch @panic("OOM"); + ke.sched.enqueue(&t.kern); } fn explodeable(_: ?*anyopaque) void { diff --git a/src/ex/init.zig b/src/ex/init.zig index d56f591..b6e0e4a 100644 --- a/src/ex/init.zig +++ b/src/ex/init.zig @@ -4,11 +4,10 @@ const pl = r.pl; const ke = r.ke; const mm = r.mm; const ex = r.ex; +const ps = r.ps; const amd64 = @import("arch"); const turnstile = ke.private.turnstile; -var thread0: ke.Thread = undefined; - var mtx: ke.private.mutex.Mutex = .init(); var shared_counter: usize = 0; @@ -20,48 +19,18 @@ fn mutex_test(_: ?*anyopaque) void { } } -fn make_thread(entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) *ke.Thread { - var ret: *ke.Thread = mm.zone.gpa.create(ke.Thread) catch @panic("oom"); - const stack = mm.heap.alloc(r.kib(64)) catch @panic("wtf"); - - std.log.info("Stack = {*}", .{stack}); - - ret.init(@intFromPtr(stack), r.kib(64), entry, arg); - - ret.priority = ke.Thread.Priority.default; - ret.base_priority = ret.priority; - ret.turnstile = mm.zone.gpa.create(ke.private.turnstile.Turnstile) catch @panic("oom"); - ret.turnstile.* = .{ - .link = undefined, - .next_free = null, - .obj = undefined, - .owner = null, - .boost_link = undefined, - .donated = null, - .queues = undefined, - .waiters = 0, - }; - - ret.turnstile.queues[0].init(); - ret.turnstile.queues[1].init(); - ret.turnstile_waiter = null; - - return ret; -} - pub fn init(boot_info: *pl.BootInfo) void { mm.init(boot_info); pl.late_init(boot_info); mm.late_init(); ke.sched.late_init(); - ke.private.turnstile.init_turnstiles(); + ps.init(); if (false) { if (boot_info.framebuffer != null) { - const sp = mm.heap.alloc(r.kib(16)) catch @panic("oom"); - thread0.init(@intFromPtr(sp), r.kib(16), ex.fireworks.start, boot_info); - ke.sched.enqueue(&thread0); + const t = ps.thread.create_kernel(ke.Thread.Priority.default, ex.fireworks.start, boot_info) catch @panic("oom"); + ke.sched.enqueue(&t.kern); } while (true) {} @@ -70,8 +39,8 @@ pub fn init(boot_info: *pl.BootInfo) void { const ipl = ke.ipl.raise(.Dispatch); for (0..10) |_| { - const t = make_thread(mutex_test, null); - ke.sched.enqueue(t); + const t = ps.thread.create_kernel(ke.Thread.Priority.default, mutex_test, null) catch @panic("oom"); + ke.sched.enqueue(&t.kern); } ke.ipl.lower(ipl); diff --git a/src/kern/init.zig b/src/kern/init.zig index 94009a4..18776ad 100644 --- a/src/kern/init.zig +++ b/src/kern/init.zig @@ -14,8 +14,9 @@ pub fn init(boot_info: *pl.BootInfo) linksection(r.init) void { std.log.info("Welcome to the machine", .{}); pl.early_init(boot_info); ki.cpu.init_cpu(0); + ki.turnstile.init_turnstiles(); - thread0.init(@intFromPtr(&stack), r.kib(16), ki.sched.idle, null); + thread0.init(@intFromPtr(&stack), r.kib(16), ke.Thread.Priority.idle, ki.sched.idle, null); thread0.priority = 0; thread0.base_priority = 0; thread0.pinned = true; diff --git a/src/kern/thread.zig b/src/kern/thread.zig index 063686d..8c6f97a 100644 --- a/src/kern/thread.zig +++ b/src/kern/thread.zig @@ -111,15 +111,16 @@ pub const Thread = struct { /// Initialize a thread. /// - `stack`: Address of the **base** of the stack on which the initial context for the thread is built /// - `stack_size`: Size of the stack + /// - `prio`: Base priority of the thread /// - `entry`: Entry point of the thread /// - `arg`: Extraneous argument to be passed to `entry` - pub fn init(thread: *Thread, stack: r.VAddr, stack_size: usize, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) void { + pub fn init(thread: *Thread, stack: r.VAddr, stack_size: usize, prio: u8, entry: *const fn (?*anyopaque) void, arg: ?*anyopaque) void { thread.* = .{ .context = .init(stack, stack_size, entry, arg), .lock = .init(), .nice = 0, - .priority = Thread.Priority.default, - .base_priority = Thread.Priority.default, + .priority = prio, + .base_priority = prio, .inherited_prio = 0, .sleep_start = 0, .sleep_time = 0, diff --git a/src/platform/pc/smp.zig b/src/platform/pc/smp.zig index 0708dc0..ab2a70c 100644 --- a/src/platform/pc/smp.zig +++ b/src/platform/pc/smp.zig @@ -40,10 +40,8 @@ fn ap_entry(cpu_id: u32) callconv(.c) noreturn { fn make_thread(entrypoint: *const fn (?*anyopaque) void, stack: usize) *ke.Thread { const td = mm.zone.gpa.create(ke.Thread) catch @panic("Failed to allocate thread for AP"); - td.init(stack, r.kib(32), entrypoint, null); + td.init(stack, r.kib(32), ke.Thread.Priority.idle, entrypoint, null); - td.priority = 0; - td.base_priority = 0; td.pinned = true; return td; } diff --git a/src/proc/private.zig b/src/proc/private.zig new file mode 100644 index 0000000..eb90a19 --- /dev/null +++ b/src/proc/private.zig @@ -0,0 +1,28 @@ +const r = @import("root"); +const ke = r.ke; +const ki = ke.private; +const mm = r.mm; + +pub const thread = @import("thread.zig"); + +pub var turnstile_zone: mm.zone.TypedZone(ki.turnstile.Turnstile) = undefined; + +fn turnstile_ctor(ts: *ki.turnstile.Turnstile) void { + ts.* = .{ + .link = undefined, + .next_free = null, + .obj = undefined, + .owner = null, + .boost_link = undefined, + .donated = null, + .queues = undefined, + .waiters = 0, + }; + ts.queues[0].init(); + ts.queues[1].init(); +} + +/// Initialize the process subsystem. +pub fn init() void { + turnstile_zone.init("turnstiles", .{ .ctor = turnstile_ctor }); +} diff --git a/src/proc/root.zig b/src/proc/root.zig new file mode 100644 index 0000000..2bfa1b2 --- /dev/null +++ b/src/proc/root.zig @@ -0,0 +1,16 @@ +//! Higher-level process management. + +// === Exported modules === +pub const private = @import("private.zig"); + +const p = private; + +// === Exported types === +pub const Thread = p.thread.Thread; + +// === Exported interfaces === +pub const thread = struct { + pub const create_kernel = p.thread.create_kernel; +}; + +pub const init = p.init; diff --git a/src/proc/thread.zig b/src/proc/thread.zig new file mode 100644 index 0000000..ab29970 --- /dev/null +++ b/src/proc/thread.zig @@ -0,0 +1,28 @@ +//! Higher-level thread management. +const r = @import("root"); +const psp = r.ps.private; +const ke = r.ke; +const ki = ke.private; +const mm = r.mm; + +const kernel_thread_stack_size = r.kib(16); + +/// Higher-level wrapper over a thread. +pub const Thread = struct { + /// Lower-level part of the thread. + kern: ke.Thread, +}; + +/// Create a kernel thread. +/// - `prio`: base priority of the thread. +/// - `entry`: entry point. +/// - `arg`: argument passed to `entry`. +pub fn create_kernel(prio: u8, entry: *const fn (arg: ?*anyopaque) void, arg: ?*anyopaque) !*Thread { + var td = try mm.zone.gpa.create(Thread); + const stack = try mm.heap.alloc(kernel_thread_stack_size); + + td.kern.init(@intFromPtr(stack), kernel_thread_stack_size, prio, entry, arg); + td.kern.turnstile = try psp.turnstile_zone.create(); + + return td; +} diff --git a/src/root.zig b/src/root.zig index c783ecf..56a2b55 100644 --- a/src/root.zig +++ b/src/root.zig @@ -6,6 +6,7 @@ pub const rtl = @import("rtl"); pub const ksyms = @import("ksyms"); pub const arch = @import("arch"); pub const mm = @import("mm/root.zig"); +pub const ps = @import("proc/root.zig"); const config = @import("config");