#include #include #include #include #define STACK_SIZE (8192) task_t* current_task = NULL; task_t* task_list = NULL; uint32_t next_pid = 1; void init_scheduler(void) { set_irq_handler(0, (irq_func_t) schedule); } void scheduler(registers_t* boot_regs) { task_t* task = malloc(sizeof(task_t)); task->id = next_pid++; task->regs = boot_regs; task->next = task; task_list = task; current_task = task; } registers_t* schedule(registers_t* regs) { if (!current_task) { return regs; } current_task->regs = regs; current_task = current_task->next; return current_task->regs; } task_t* create_task(void (*entry)()) { task_t* task = malloc(sizeof(task_t)); uint32_t* stack = malloc(STACK_SIZE); uint32_t stack_top = (uint32_t)stack + 4096; stack_top -= sizeof(registers_t); registers_t* regs = (registers_t*)stack_top; memset(regs, 0, sizeof(registers_t)); regs->eip = (uint32_t) entry; regs->cs = 0x08; /* kernel code */ regs->ds = 0x10; regs->es = 0x10; regs->fs = 0x10; regs->gs = 0x10; regs->eflags = 0x202; /* IF = 1 */ task->id = next_pid++; task->regs = regs; /* insert into circular list */ task->next = task_list->next; task_list->next = task; return task; }