use arch;
use arch::mem;
use objects;
use log;
// TODO: Store these globals with physical addresses
// The currently running process. Not valid during system initialization.
export let active: *objects::taskstate = null: *objects::taskstate;
// Linked list of active tasks. Not valid during system initialization.
export let tasks: *objects::taskstate = null: *objects::taskstate;
// Adds a new task to the linked list of active tasks.
export fn addtask(state: *objects::taskstate) void = {
let head = tasks;
state.prev = null;
state.next = head;
if (head == null) {
tasks = state;
} else {
tasks = state;
head.prev = state;
};
};
// Removes a task from the list of active tasks.
export fn rmtask(state: *objects::taskstate) void = {
match (state.prev) {
case let prev: *objects::taskstate =>
prev.next = state.next;
case null =>
match (state.next) {
case null =>
log::printfln("Warning: last task terminated, entering permanent idle");
for (true) arch::pause();
case let task: *objects::taskstate =>
tasks = task;
};
};
match (state.next) {
case let next: *objects::taskstate =>
next.prev = state.prev;
case null =>
yield;
};
if (state == active) {
yieldtask();
};
};