#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",
*/
/* 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) */
* 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
-OBJECTS = main.o process.o
+OBJECTS = main.o process.o sched.o
OUTPUT = core.o
INCLUDES = -I../include -I../../include -I../..
CFLAGS += $(INCLUDES)
--- /dev/null
+#include <config.h>
+#include <corax/types.h>
+#include <corax/heap.h>
+#include <debug.h>
+#include <arch.h>
+
+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;
+}