mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 13:58:20 +00:00
ps: initial process subsystem
This commit is contained in:
+6
-29
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user