77 lines
1.3 KiB
C
77 lines
1.3 KiB
C
|
|
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include <drivers/irq.h>
|
||
|
|
|
||
|
|
#include <scheduler.h>
|
||
|
|
|
||
|
|
|
||
|
|
#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;
|
||
|
|
}
|