From ec7ee599a1030b3e3c730fa542018e6624783e4d Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Sat, 14 Dec 2019 23:42:28 +0100 Subject: [PATCH] Step 2: schedule() --- src/console.zig | 34 ++++++++++-------- src/main.zig | 10 +++--- src/task.zig | 92 ++++++++++++++++++++++++++++++------------------- src/vga.zig | 4 +-- src/vmem.zig | 2 +- 5 files changed, 86 insertions(+), 56 deletions(-) diff --git a/src/console.zig b/src/console.zig index 5bf36fe..369bd84 100644 --- a/src/console.zig +++ b/src/console.zig @@ -1,15 +1,13 @@ usingnamespace @import("index.zig"); +// shitty ring buffer, fight me. +var input_ring_buffer: [1024]u8 = [_]u8{0} ** 1024; +var input_read_index: u10 = 0; +var input_write_index: u10 = 0; + var command: [10]u8 = undefined; var command_len: usize = 0; -fn test_a() void { - var a: u32 = 2; - a += 1; - a = 4; - a -= 1; -} - fn execute(input: []u8) void { const eql = std.mem.eql; if (eql(u8, input, "x86paging")) return x86.paging.introspect(); @@ -18,10 +16,6 @@ fn execute(input: []u8) void { if (eql(u8, input, "lspci")) return pci.lspci(); if (eql(u8, input, "uptime")) return time.uptime(); if (eql(u8, input, "topbar")) return topbar(); - if (eql(u8, input, "test")) { - const tbar = task.Task.new(@ptrToInt(topbar)) catch unreachable; - while (true) tbar.switch_to(); - } println("{}: command not found", input); } @@ -52,7 +46,19 @@ pub fn keypress(char: u8) void { } } -pub fn initialize() void { - ps2.keyboard_callback = keypress; - print("> "); +pub fn buffer_write(char: u8) void { + input_ring_buffer[input_write_index] = char; + input_write_index +%= 1; +} + +pub fn loop() void { + ps2.keyboard_callback = buffer_write; + print("> "); + while (true) { + if (input_write_index - input_read_index > 0) { + keypress(input_ring_buffer[input_read_index]); + input_read_index +%= 1; + } + task.schedule(); + } } diff --git a/src/main.zig b/src/main.zig index dede56b..82cf7a0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,8 +25,10 @@ export fn kmain(magic: u32, info: *const multiboot.MultibootInfo) noreturn { vmem.initialize(); pci.scan(); - console.initialize(); - // while (true) asm volatile ("hlt"); - const tbar = task.Task.new(@ptrToInt(topbar)) catch unreachable; - while (true) tbar.switch_to(); + task.new(@ptrToInt(topbar)) catch unreachable; + // task.new(@ptrToInt(console.loop)) catch unreachable; + + // task.schedule(); + console.loop(); + while (true) asm volatile ("hlt"); } diff --git a/src/task.zig b/src/task.zig index 75c5cee..281eba3 100644 --- a/src/task.zig +++ b/src/task.zig @@ -1,8 +1,14 @@ pub usingnamespace @import("index.zig"); -const TASK_MAX = 1024; + var boot_task = Task{ .tid = 0, .esp = 0x47 }; -var current_task: *Task = &boot_task; -pub var tasks = [1]?*Task{&boot_task} ++ ([1]?*Task{null} ** TASK_MAX); +const ListOfTasks = std.TailQueue(*Task); +var first_task = ListOfTasks.Node.init(&boot_task); +var current_task = &first_task; +var tasks = ListOfTasks{ + .first = &first_task, + .last = &first_task, + .len = 1, +}; const STACK_SIZE = x86.PAGE_SIZE; // Size of thread stacks. var tid_counter: u16 = 1; @@ -16,9 +22,9 @@ pub const Task = packed struct { //context: isr.Context, //cr3: usize, - pub fn new(entrypoint: usize) !*Task { + pub fn create(entrypoint: usize) !*Task { // Allocate and initialize the thread structure. - var t = try vmem.allocate(Task); + var t = try vmem.create(Task); t.tid = tid_counter; tid_counter +%= 1; @@ -33,46 +39,62 @@ pub const Task = packed struct { t.esp -= 4; @intToPtr(*usize, t.esp).* = t.esp + 8; - println("new task esp=0x{x}, eip=0x{x}", t.esp, entrypoint); - - tasks[t.tid] = t; return t; } pub fn destroy(self: *Task) void { - tasks[self.tid] = null; vmem.free(self.esp); vmem.free(@ptrToInt(self)); } - - pub fn switch_to(self: *Task) void { - assert(self != current_task); - // save old stack - const old_task_esp_addr = ¤t_task.esp; - current_task = self; - // x86.cli(); - // don't inline the asm function, it needs to ret - @noInlineCall(switch_tasks, self.esp, @ptrToInt(old_task_esp_addr)); - // comptime { - // asm ( - // \\mov +8(%esp), %eax - // \\mov %esp, (%eax) - // \\mov +4(%esp), %eax - // \\mov %eax, %esp - // \\pop %ebp - // \\ret - // ); - // } - // x86.sti(); - println("after switch"); - } }; +pub fn new(entrypoint: usize) !void { + // println("currently: {}", current_task.data.tid); + // println("first: {}", tasks.first.?.data.tid); + // println("last: {}", tasks.last.?.data.tid); + const node = try vmem.create(ListOfTasks.Node); + node.data = try Task.create(entrypoint); + tasks.append(node); + // println("currently: {}", current_task.data.tid); + // println("first: {}", tasks.first.?.data.tid); + // println("last: {}", tasks.last.?.data.tid); +} + +pub fn switch_to(new_task: *ListOfTasks.Node) void { + assert(new_task.data != current_task.data); + // save old stack + const old_task_esp_addr = ¤t_task.data.esp; + current_task = new_task; + // x86.cli(); + // don't inline the asm function, it needs to ret + @noInlineCall(switch_tasks, new_task.data.esp, @ptrToInt(old_task_esp_addr)); + // x86.sti(); +} + +pub fn schedule() void { + // println("currently: {}", current_task.data.tid); + // println("first: {}", tasks.first.?.data.tid); + // println("last: {}", tasks.last.?.data.tid); + if (current_task.next) |next| { + // println("switching to {}", next.data.tid); + switch_to(next); + } else if (tasks.first) |head| { + // println("switching to {}", head.data.tid); + if (head.data != current_task.data) switch_to(head); + } else { + introspect(); + } + // if (current_task.data.tid == 0) switch_to(tasks.last.?.*); + // if (current_task.data.tid == 1) switch_to(tasks.first.?.*); + // if (current_task.tid == 2) tasks[0].?.switch_to(); +} + pub fn introspect() void { - for (tasks) |t| { - if (t == null) continue; - if (t != current_task) println("{}", t); - if (t == current_task) println("*{}", t); + var it = tasks.first; + println("{} tasks", tasks.len); + while (it) |node| : (it = node.next) { + if (node.data != current_task.data) println("{}", node.data); + if (node.data == current_task.data) println("*{}", node.data); } } diff --git a/src/vga.zig b/src/vga.zig index d67c025..ecf1349 100644 --- a/src/vga.zig +++ b/src/vga.zig @@ -63,9 +63,9 @@ pub fn clear() void { vga.clear(); } pub fn topbar() void { - const cursor = vga.cursor; const bg = vga.background; while (true) { + const cursor = vga.cursor; vga.cursor = 0; vga.background = Color.Red; @@ -73,7 +73,7 @@ pub fn topbar() void { vga.cursor = cursor; vga.background = bg; - task.tasks[0].?.switch_to(); + task.schedule(); } } diff --git a/src/vmem.zig b/src/vmem.zig index ece503f..a38a9db 100644 --- a/src/vmem.zig +++ b/src/vmem.zig @@ -22,7 +22,7 @@ pub fn malloc(size: usize) !usize { return vaddr; } -pub fn allocate(comptime T: type) !*T { +pub fn create(comptime T: type) !*T { assert(@sizeOf(T) < x86.PAGE_SIZE); // this allocator only support 1:1 mapping return @intToPtr(*T, try malloc(@sizeOf(T))); }