Step 2: schedule()

This commit is contained in:
Jack Halford 2019-12-14 23:42:28 +01:00
parent 6af31b5b89
commit ec7ee599a1
5 changed files with 86 additions and 56 deletions

View file

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

View file

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

View file

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

View file

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

View file

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