From: Matthias Kruk Date: Fri, 27 Sep 2019 07:10:31 +0000 (+0900) Subject: Add a _very_ naive scheduler X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=4172508cb546b3ded3b6447e7f1338e053d6bf93;p=corax Add a _very_ naive scheduler --- diff --git a/kernel/arch/interrupt.c b/kernel/arch/interrupt.c index b8b9677..8649a4a 100644 --- a/kernel/arch/interrupt.c +++ b/kernel/arch/interrupt.c @@ -22,6 +22,8 @@ #include "cpu.h" #include "defs.h" +void sched_tick(void); + static const char *_exc_name[] = { "#DE", "#DB", "NMI", "#BP", "#OF", "#BR", "#UD", "#NM", "#DF", "#MF", "#TS", "#NP", "#SS", "#GP", "#PF", "RESV", "#MF", "#AC", "#MC", "#XM", @@ -61,7 +63,8 @@ int _int_handle(stack_frame_t ctx) */ /* PANIC("Unhandled interrupt"); */ - if(ctx.intn == INT_KEYBOARD) { + switch(ctx.intn) { + case INT_KEYBOARD: { #if FEATURE(DEBUG) extern struct cpu _cpu[CONFIG_SMP_CPUS]; #endif /* FEATURE(DEBUG) */ @@ -80,8 +83,16 @@ int _int_handle(stack_frame_t ctx) * could not cause a triple fault */ asm volatile("ljmp $0x30, $0xfee00020"); /* LEEROY JENKINS!!! */ #endif /* FEATURE(DEBUG) */ - } else if(ctx.intn != INT_TIMER) { + break; + } + + case INT_TIMER: + sched_tick(); + break; + + default: dbg_printf("Interrupt %u occurred\n", ctx.intn); + break; } #if CONFIG_APIC == 1 diff --git a/kernel/core/Makefile b/kernel/core/Makefile index bb68e27..47a3eea 100644 --- a/kernel/core/Makefile +++ b/kernel/core/Makefile @@ -1,4 +1,4 @@ -OBJECTS = main.o process.o +OBJECTS = main.o process.o sched.o OUTPUT = core.o INCLUDES = -I../include -I../../include -I../.. CFLAGS += $(INCLUDES) diff --git a/kernel/core/sched.c b/kernel/core/sched.c new file mode 100644 index 0000000..497d504 --- /dev/null +++ b/kernel/core/sched.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +struct task_queue { + struct task_queue *next; + task_t *data; +}; + +/* FIXME: This should be per-processor */ +static struct task_queue *_readyq; + +static void _nq(struct task_queue **q, task_t *t) +{ + struct task_queue *item; + + item = kmalloc(sizeof(*item)); + + if(item) { + item->data = t; + + /* get a pointer to the end of the queue */ + while(*q) { + q = &((*q)->next); + } + + item->next = *q; + *q = item; + } + + return; +} + +static task_t* _dq(struct task_queue **q) +{ + struct task_queue *cur; + task_t *ret_val; + + cur = *q; + ret_val = NULL; + + if(cur) { + *q = cur->next; + ret_val = cur->data; + + kfree(cur); + } + + return(ret_val); +} + +void sched_tick(void) +{ + task_t *cur_task; + + cur_task = task_get_current(); + + if(cur_task) { + /* check if running task has not used up it's quantum yet */ + if(cur_task->t_rslice) { + cur_task->t_rslice--; + return; + } + + /* task's time is up - reschedule */ + cur_task->t_rslice = cur_task->t_tslice; + cur_task->t_state = TASK_STATE_READY; + + /* put the task back on the ready queue */ + _nq(&_readyq, cur_task); + + /* get the next task from the ready queue */ + cur_task = _dq(&_readyq); + + if(cur_task) { + task_set_current(cur_task); + } else { + dbg_printf("This should not have happened\n"); + } + } + + return; +}