Step 5: lock/unlock scheduler

This commit is contained in:
Jack Halford 2019-12-15 12:46:09 +01:00
parent b3d8b7abc7
commit f2d2ab867e
8 changed files with 37 additions and 10 deletions

View file

@ -1 +0,0 @@
pub const PAGE_SIZE: usize = 4096;

View file

@ -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");

View file

@ -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
View file

@ -0,0 +1 @@
pub const SMP: bool = false;

View file

@ -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");

View file

@ -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();
}
} }

View file

@ -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 = &current_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 = &current_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();

View file

@ -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();
} }
} }