diff options
-rw-r--r-- | src/include/kernel/cpumgr.H | 2 | ||||
-rw-r--r-- | src/include/kernel/scheduler.H | 5 | ||||
-rw-r--r-- | src/include/kernel/taskmgr.H | 1 | ||||
-rw-r--r-- | src/kernel/makefile | 2 | ||||
-rw-r--r-- | src/kernel/scheduler.C | 35 | ||||
-rw-r--r-- | src/kernel/syscall.C | 9 | ||||
-rw-r--r-- | src/kernel/taskmgr.C | 7 |
7 files changed, 58 insertions, 3 deletions
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H index 06ca8dbc1..325f09d32 100644 --- a/src/include/kernel/cpumgr.H +++ b/src/include/kernel/cpumgr.H @@ -12,7 +12,7 @@ class CpuManager * Returns a pointer to the current CPU structure by using the * task structure in SPRG3. */ - cpu_t* getCurrentCPU(); + static cpu_t* getCurrentCPU(); static void init(); diff --git a/src/include/kernel/scheduler.H b/src/include/kernel/scheduler.H index 06c3adcee..93854ac3b 100644 --- a/src/include/kernel/scheduler.H +++ b/src/include/kernel/scheduler.H @@ -9,6 +9,11 @@ class Scheduler public: friend class CpuManager; + void addTask(task_t*); + + void returnRunnable(); + void setNextRunnable(); + protected: Scheduler() : iv_direction(false) {}; ~Scheduler() {}; diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H index 7f23c8821..939757fde 100644 --- a/src/include/kernel/taskmgr.H +++ b/src/include/kernel/taskmgr.H @@ -7,6 +7,7 @@ class TaskManager { public: static task_t* getCurrentTask(); + static void setCurrentTask(task_t* t); typedef void(*task_fn_t)(); diff --git a/src/kernel/makefile b/src/kernel/makefile index d3a586e8d..c07ae815a 100644 --- a/src/kernel/makefile +++ b/src/kernel/makefile @@ -2,7 +2,7 @@ OBJDIR = ../../obj include ../../config.mk OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o -OBJS += syscall.o +OBJS += syscall.o scheduler.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) all: ${OBJECTS} diff --git a/src/kernel/scheduler.C b/src/kernel/scheduler.C new file mode 100644 index 000000000..1df91b9eb --- /dev/null +++ b/src/kernel/scheduler.C @@ -0,0 +1,35 @@ +#include <kernel/task.H> +#include <kernel/scheduler.H> +#include <kernel/taskmgr.H> + +void Scheduler::addTask(task_t* t) +{ + if (iv_idleTask != t) + iv_taskList[iv_direction ? 0 : 1].push(t); +} + +void Scheduler::returnRunnable() +{ + this->addTask(TaskManager::getCurrentTask()); +} + +void Scheduler::setNextRunnable() +{ + task_t* t = NULL; + + bool direction = iv_direction; + t = iv_taskList[direction ? 1 : 0].pop(); + + if (NULL == t) + { + iv_taskList[direction ? 0 : 1].pop(); + __sync_bool_compare_and_swap(&iv_direction, direction, !direction); + } + + if (NULL == t) + { + t = iv_idleTask; + } + + TaskManager::setCurrentTask(t); +} diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index d59ea1a03..0b591f575 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -1,10 +1,17 @@ #include <kernel/console.H> +#include <kernel/cpu.H> +#include <kernel/cpumgr.H> +#include <kernel/scheduler.H> extern "C" void kernel_execute_decrementer() { //printk("Decrementer.\n"); - + + Scheduler* s = CpuManager::getCurrentCPU()->scheduler; + s->returnRunnable(); + s->setNextRunnable(); + // Resync decrementer. register uint64_t decrementer = 0x0f000000; asm volatile("mtdec %0" :: "r"(decrementer)); diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C index a3dcdf5f3..50b9a0848 100644 --- a/src/kernel/taskmgr.C +++ b/src/kernel/taskmgr.C @@ -17,6 +17,13 @@ task_t* TaskManager::getCurrentTask() return current_task; } +void TaskManager::setCurrentTask(task_t* t) +{ + register task_t* _t = t; + asm volatile("mtsprg3 %0" :: "r" (_t)); + return; +} + TaskManager::TaskManager() : iv_nextTid(0) { } |