Step 4: task states

This commit is contained in:
Jack Halford 2019-12-15 11:46:47 +01:00
parent 27e6f2684b
commit b3d8b7abc7
2 changed files with 32 additions and 17 deletions

View file

@ -59,12 +59,7 @@ pub fn initialize() void {
isr.install_syscalls(); isr.install_syscalls();
interrupt.registerIRQ(0, interrupt.pit_handler); interrupt.registerIRQ(0, interrupt.pit_handler);
interrupt.registerIRQ(1, kernel.ps2.keyboard_handler); interrupt.registerIRQ(1, kernel.ps2.keyboard_handler);
interrupt.register(3, test_b);
// load IDT // load IDT
lidt(@ptrToInt(&idtr)); lidt(@ptrToInt(&idtr));
} }
pub fn test_b() void {
kernel.println("int3!");
}

View file

@ -1,7 +1,7 @@
pub usingnamespace @import("index.zig"); pub usingnamespace @import("index.zig");
var timer_last_count: u64 = 0; var timer_last_count: u64 = 0;
var boot_task = Task{ .tid = 0, .esp = 0x47 }; var boot_task = Task{ .tid = 0, .esp = 0x47, .state = .Running };
const ListOfTasks = std.TailQueue(*Task); const ListOfTasks = std.TailQueue(*Task);
var first_task = ListOfTasks.Node.init(&boot_task); var first_task = ListOfTasks.Node.init(&boot_task);
var current_task = &first_task; var current_task = &first_task;
@ -24,10 +24,16 @@ pub fn update_time_used() void {
current_task.data.time_used += elapsed; current_task.data.time_used += elapsed;
} }
pub const Task = packed struct { pub const TaskState = enum {
Running,
ReadyToRun,
};
pub const Task = struct {
esp: usize, esp: usize,
tid: u16, tid: u16,
time_used: u64 = 0, time_used: u64 = 0,
state: TaskState,
//context: isr.Context, //context: isr.Context,
//cr3: usize, //cr3: usize,
@ -36,6 +42,7 @@ pub const Task = packed struct {
var t = try vmem.create(Task); var t = try vmem.create(Task);
t.time_used = 0; t.time_used = 0;
t.state = .ReadyToRun;
t.tid = tid_counter; t.tid = tid_counter;
tid_counter +%= 1; tid_counter +%= 1;
assert(tid_counter != 0); //overflow assert(tid_counter != 0); //overflow
@ -66,6 +73,11 @@ 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);
// switch states
current_task.data.state = .ReadyToRun;
new_task.data.state = .Running;
// save old stack // save old stack
const old_task_esp_addr = &current_task.data.esp; const old_task_esp_addr = &current_task.data.esp;
current_task = new_task; current_task = new_task;
@ -75,23 +87,31 @@ pub fn switch_to(new_task: *ListOfTasks.Node) void {
// x86.sti(); // x86.sti();
} }
// circular next
pub fn next(node: *ListOfTasks.Node) ?*ListOfTasks.Node {
return if (node.next) |n| n else tasks.first;
}
pub fn first_ready_to_run() ?*ListOfTasks.Node {
var node = current_task;
while (next(node)) |n| {
if (n.data.state == .ReadyToRun) return n;
if (n.data.state == .Running) return null;
}
return null;
}
pub fn schedule() void { pub fn schedule() void {
update_time_used(); update_time_used();
if (current_task.next) |next| { if (first_ready_to_run()) |t| switch_to(t);
switch_to(next);
} else if (tasks.first) |head| {
if (head.data != current_task.data) switch_to(head);
}
} }
pub fn introspect() void { pub fn introspect() void {
update_time_used();
var it = tasks.first; var it = tasks.first;
println("{} tasks", tasks.len); println("{} tasks", tasks.len);
update_time_used(); while (it) |node| : (it = node.next) println("{}", node.data);
while (it) |node| : (it = node.next) {
if (node.data != current_task.data) println("{}", node.data);
if (node.data == current_task.data) println("*{}", node.data);
}
} }
// fn initContext(entry_point: usize, stack: usize) isr.Context { // fn initContext(entry_point: usize, stack: usize) isr.Context {