ps: initial process subsystem

This commit is contained in:
Loïc Grégoire
2026-06-18 18:54:38 -04:00
parent 42b10b886e
commit e50b1e0167
9 changed files with 92 additions and 73 deletions
+6 -29
View File
@@ -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 {
+6 -37
View File
@@ -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);
+2 -1
View File
@@ -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;
+4 -3
View File
@@ -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,
+1 -3
View File
@@ -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;
}
+28
View File
@@ -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 });
}
+16
View File
@@ -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;
+28
View File
@@ -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;
}
+1
View File
@@ -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");