mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-02 08:08:21 +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 r = @import("root");
|
||||||
const ke = r.ke;
|
const ke = r.ke;
|
||||||
const mm = r.mm;
|
const mm = r.mm;
|
||||||
|
const ps = r.ps;
|
||||||
const sintab = @import("sintab.zig");
|
const sintab = @import("sintab.zig");
|
||||||
|
|
||||||
var pixel_buffer: [*]u8 = undefined;
|
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;
|
@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 {
|
fn rand_tsc_based() u32 {
|
||||||
const tsc = read_tsc();
|
const tsc = ke.time.read_time();
|
||||||
const lo: u32 = @truncate(tsc);
|
const lo: u32 = @truncate(tsc);
|
||||||
const hi: u32 = @truncate(tsc >> 32);
|
const hi: u32 = @truncate(tsc >> 32);
|
||||||
return lo ^ hi;
|
return lo ^ hi;
|
||||||
@@ -163,26 +152,14 @@ fn particle(param: ?*anyopaque) void {
|
|||||||
ke.sched.block();
|
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 {
|
fn spawn_particle(arg: ?*anyopaque) void {
|
||||||
const thread = make_thread(&particle, arg);
|
const t = ps.thread.create_kernel(ke.Thread.Priority.default, &particle, arg) catch @panic("OOM");
|
||||||
ke.sched.enqueue(thread);
|
ke.sched.enqueue(&t.kern);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_explodeable() void {
|
fn spawn_explodeable() void {
|
||||||
const thread = make_thread(&explodeable, null);
|
const t = ps.thread.create_kernel(ke.Thread.Priority.default, &explodeable, null) catch @panic("OOM");
|
||||||
ke.sched.enqueue(thread);
|
ke.sched.enqueue(&t.kern);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explodeable(_: ?*anyopaque) void {
|
fn explodeable(_: ?*anyopaque) void {
|
||||||
|
|||||||
+6
-37
@@ -4,11 +4,10 @@ const pl = r.pl;
|
|||||||
const ke = r.ke;
|
const ke = r.ke;
|
||||||
const mm = r.mm;
|
const mm = r.mm;
|
||||||
const ex = r.ex;
|
const ex = r.ex;
|
||||||
|
const ps = r.ps;
|
||||||
const amd64 = @import("arch");
|
const amd64 = @import("arch");
|
||||||
const turnstile = ke.private.turnstile;
|
const turnstile = ke.private.turnstile;
|
||||||
|
|
||||||
var thread0: ke.Thread = undefined;
|
|
||||||
|
|
||||||
var mtx: ke.private.mutex.Mutex = .init();
|
var mtx: ke.private.mutex.Mutex = .init();
|
||||||
var shared_counter: usize = 0;
|
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 {
|
pub fn init(boot_info: *pl.BootInfo) void {
|
||||||
mm.init(boot_info);
|
mm.init(boot_info);
|
||||||
|
|
||||||
pl.late_init(boot_info);
|
pl.late_init(boot_info);
|
||||||
mm.late_init();
|
mm.late_init();
|
||||||
ke.sched.late_init();
|
ke.sched.late_init();
|
||||||
ke.private.turnstile.init_turnstiles();
|
ps.init();
|
||||||
|
|
||||||
if (false) {
|
if (false) {
|
||||||
if (boot_info.framebuffer != null) {
|
if (boot_info.framebuffer != null) {
|
||||||
const sp = mm.heap.alloc(r.kib(16)) catch @panic("oom");
|
const t = ps.thread.create_kernel(ke.Thread.Priority.default, ex.fireworks.start, boot_info) catch @panic("oom");
|
||||||
thread0.init(@intFromPtr(sp), r.kib(16), ex.fireworks.start, boot_info);
|
ke.sched.enqueue(&t.kern);
|
||||||
ke.sched.enqueue(&thread0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {}
|
while (true) {}
|
||||||
@@ -70,8 +39,8 @@ pub fn init(boot_info: *pl.BootInfo) void {
|
|||||||
const ipl = ke.ipl.raise(.Dispatch);
|
const ipl = ke.ipl.raise(.Dispatch);
|
||||||
|
|
||||||
for (0..10) |_| {
|
for (0..10) |_| {
|
||||||
const t = make_thread(mutex_test, null);
|
const t = ps.thread.create_kernel(ke.Thread.Priority.default, mutex_test, null) catch @panic("oom");
|
||||||
ke.sched.enqueue(t);
|
ke.sched.enqueue(&t.kern);
|
||||||
}
|
}
|
||||||
|
|
||||||
ke.ipl.lower(ipl);
|
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", .{});
|
std.log.info("Welcome to the machine", .{});
|
||||||
pl.early_init(boot_info);
|
pl.early_init(boot_info);
|
||||||
ki.cpu.init_cpu(0);
|
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.priority = 0;
|
||||||
thread0.base_priority = 0;
|
thread0.base_priority = 0;
|
||||||
thread0.pinned = true;
|
thread0.pinned = true;
|
||||||
|
|||||||
+4
-3
@@ -111,15 +111,16 @@ pub const Thread = struct {
|
|||||||
/// Initialize a thread.
|
/// Initialize a thread.
|
||||||
/// - `stack`: Address of the **base** of the stack on which the initial context for the thread is built
|
/// - `stack`: Address of the **base** of the stack on which the initial context for the thread is built
|
||||||
/// - `stack_size`: Size of the stack
|
/// - `stack_size`: Size of the stack
|
||||||
|
/// - `prio`: Base priority of the thread
|
||||||
/// - `entry`: Entry point of the thread
|
/// - `entry`: Entry point of the thread
|
||||||
/// - `arg`: Extraneous argument to be passed to `entry`
|
/// - `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.* = .{
|
thread.* = .{
|
||||||
.context = .init(stack, stack_size, entry, arg),
|
.context = .init(stack, stack_size, entry, arg),
|
||||||
.lock = .init(),
|
.lock = .init(),
|
||||||
.nice = 0,
|
.nice = 0,
|
||||||
.priority = Thread.Priority.default,
|
.priority = prio,
|
||||||
.base_priority = Thread.Priority.default,
|
.base_priority = prio,
|
||||||
.inherited_prio = 0,
|
.inherited_prio = 0,
|
||||||
.sleep_start = 0,
|
.sleep_start = 0,
|
||||||
.sleep_time = 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 {
|
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");
|
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;
|
td.pinned = true;
|
||||||
return td;
|
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 ksyms = @import("ksyms");
|
||||||
pub const arch = @import("arch");
|
pub const arch = @import("arch");
|
||||||
pub const mm = @import("mm/root.zig");
|
pub const mm = @import("mm/root.zig");
|
||||||
|
pub const ps = @import("proc/root.zig");
|
||||||
|
|
||||||
const config = @import("config");
|
const config = @import("config");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user