Step 5: lock/unlock scheduler
This commit is contained in:
parent
b3d8b7abc7
commit
f2d2ab867e
8 changed files with 37 additions and 10 deletions
|
|
@ -1 +0,0 @@
|
||||||
pub const PAGE_SIZE: usize = 4096;
|
|
||||||
|
|
@ -6,10 +6,10 @@ pub const assert = std.debug.assert;
|
||||||
pub const kernel = @import("../../index.zig");
|
pub const kernel = @import("../../index.zig");
|
||||||
|
|
||||||
// x86 namespace
|
// x86 namespace
|
||||||
|
pub const PAGE_SIZE: usize = 4096;
|
||||||
pub usingnamespace @import("lib/io.zig");
|
pub usingnamespace @import("lib/io.zig");
|
||||||
pub usingnamespace @import("lib/instructions.zig");
|
pub usingnamespace @import("lib/instructions.zig");
|
||||||
pub usingnamespace @import("main.zig");
|
pub usingnamespace @import("main.zig");
|
||||||
pub usingnamespace @import("constants.zig");
|
|
||||||
pub const pmem = @import("pmem.zig");
|
pub const pmem = @import("pmem.zig");
|
||||||
pub const paging = @import("paging.zig");
|
pub const paging = @import("paging.zig");
|
||||||
pub const idt = @import("idt.zig");
|
pub const idt = @import("idt.zig");
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ pub fn loop() void {
|
||||||
keypress(input_ring_buffer[input_read_index]);
|
keypress(input_ring_buffer[input_read_index]);
|
||||||
input_read_index +%= 1;
|
input_read_index +%= 1;
|
||||||
}
|
}
|
||||||
|
task.lock_scheduler();
|
||||||
task.schedule();
|
task.schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
src/constants.zig
Normal file
1
src/constants.zig
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub const SMP: bool = false;
|
||||||
|
|
@ -8,6 +8,7 @@ pub usingnamespace @import("vga.zig");
|
||||||
pub const x86 = @import("arch/x86/index.zig");
|
pub const x86 = @import("arch/x86/index.zig");
|
||||||
|
|
||||||
///core
|
///core
|
||||||
|
pub const constants = @import("constants.zig");
|
||||||
pub const layout = @import("layout.zig");
|
pub const layout = @import("layout.zig");
|
||||||
pub const multiboot = @import("multiboot.zig");
|
pub const multiboot = @import("multiboot.zig");
|
||||||
pub const vmem = @import("vmem.zig");
|
pub const vmem = @import("vmem.zig");
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,8 @@ export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn {
|
||||||
task.new(@ptrToInt(topbar)) catch unreachable;
|
task.new(@ptrToInt(topbar)) catch unreachable;
|
||||||
task.new(@ptrToInt(console.loop)) catch unreachable;
|
task.new(@ptrToInt(console.loop)) catch unreachable;
|
||||||
|
|
||||||
while (true) task.schedule();
|
while (true) {
|
||||||
|
task.lock_scheduler();
|
||||||
|
task.schedule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
src/task.zig
34
src/task.zig
|
|
@ -49,10 +49,10 @@ pub const Task = struct {
|
||||||
|
|
||||||
// allocate a new stack
|
// allocate a new stack
|
||||||
t.esp = (try vmem.malloc(STACK_SIZE)) + STACK_SIZE;
|
t.esp = (try vmem.malloc(STACK_SIZE)) + STACK_SIZE;
|
||||||
// top of stack is the address that ret will pop
|
// this will be what ret goes to
|
||||||
t.esp -= 4;
|
t.esp -= 4;
|
||||||
@intToPtr(*usize, t.esp).* = entrypoint;
|
@intToPtr(*usize, t.esp).* = entrypoint;
|
||||||
// top of stack is ebp that we will pop
|
// this will be popped into ebp
|
||||||
t.esp -= 4;
|
t.esp -= 4;
|
||||||
@intToPtr(*usize, t.esp).* = t.esp + 8;
|
@intToPtr(*usize, t.esp).* = t.esp + 8;
|
||||||
|
|
||||||
|
|
@ -74,17 +74,18 @@ pub fn new(entrypoint: usize) !void {
|
||||||
pub fn switch_to(new_task: *ListOfTasks.Node) void {
|
pub fn switch_to(new_task: *ListOfTasks.Node) void {
|
||||||
assert(new_task.data != current_task.data);
|
assert(new_task.data != current_task.data);
|
||||||
|
|
||||||
|
// save old stack
|
||||||
|
const old_task_esp_addr = ¤t_task.data.esp;
|
||||||
|
|
||||||
// switch states
|
// switch states
|
||||||
current_task.data.state = .ReadyToRun;
|
current_task.data.state = .ReadyToRun;
|
||||||
new_task.data.state = .Running;
|
new_task.data.state = .Running;
|
||||||
|
|
||||||
// save old stack
|
|
||||||
const old_task_esp_addr = ¤t_task.data.esp;
|
|
||||||
current_task = new_task;
|
current_task = new_task;
|
||||||
// x86.cli();
|
|
||||||
|
unlock_scheduler();
|
||||||
|
|
||||||
// don't inline the asm function, it needs to ret
|
// don't inline the asm function, it needs to ret
|
||||||
@noInlineCall(switch_tasks, new_task.data.esp, @ptrToInt(old_task_esp_addr));
|
@noInlineCall(switch_tasks, new_task.data.esp, @ptrToInt(old_task_esp_addr));
|
||||||
// x86.sti();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// circular next
|
// circular next
|
||||||
|
|
@ -106,6 +107,25 @@ pub fn schedule() void {
|
||||||
if (first_ready_to_run()) |t| switch_to(t);
|
if (first_ready_to_run()) |t| switch_to(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var IRQ_disable_counter: usize = 0;
|
||||||
|
|
||||||
|
pub fn lock_scheduler() void {
|
||||||
|
if (constants.SMP == false) {
|
||||||
|
x86.cli();
|
||||||
|
IRQ_disable_counter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn unlock_scheduler() void {
|
||||||
|
if (IRQ_disable_counter == 0) {
|
||||||
|
println("trying to unlock here");
|
||||||
|
while (true) asm volatile ("hlt");
|
||||||
|
}
|
||||||
|
if (constants.SMP == false) {
|
||||||
|
IRQ_disable_counter -= 1;
|
||||||
|
if (IRQ_disable_counter == 0) x86.sti();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn introspect() void {
|
pub fn introspect() void {
|
||||||
update_time_used();
|
update_time_used();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ pub fn topbar() void {
|
||||||
vga.cursor_enabled = true;
|
vga.cursor_enabled = true;
|
||||||
vga.cursor = cursor;
|
vga.cursor = cursor;
|
||||||
vga.background = bg;
|
vga.background = bg;
|
||||||
|
|
||||||
|
task.lock_scheduler();
|
||||||
task.schedule();
|
task.schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue