Step 2: schedule()
This commit is contained in:
parent
6af31b5b89
commit
ec7ee599a1
5 changed files with 86 additions and 56 deletions
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/main.zig
10
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");
|
||||
}
|
||||
|
|
|
|||
92
src/task.zig
92
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue