diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-06-07 16:39:45 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-06-07 16:39:45 -0500 |
commit | 9a4698af6ee4c095a97b8800d2d5f0a4bb282b15 (patch) | |
tree | 9f5241ee1f91d21c8043b359d7bfaeb309ecd5b8 | |
parent | aa1db69f1de27bba8ee5e128f717557780f21e0d (diff) | |
download | talos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.tar.gz talos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.zip |
Add task control syscalls.
-rw-r--r-- | src/include/kernel/syscalls.H | 3 | ||||
-rw-r--r-- | src/include/kernel/task.H | 2 | ||||
-rw-r--r-- | src/include/kernel/taskmgr.H | 3 | ||||
-rw-r--r-- | src/include/sys/syscall.h | 2 | ||||
-rw-r--r-- | src/include/sys/task.h | 20 | ||||
-rw-r--r-- | src/kernel/syscall.C | 47 | ||||
-rw-r--r-- | src/kernel/taskmgr.C | 3 | ||||
-rw-r--r-- | src/lib/makefile | 3 | ||||
-rw-r--r-- | src/lib/syscall_task.C | 26 | ||||
-rw-r--r-- | src/sys/init/init_main.C | 14 |
10 files changed, 115 insertions, 8 deletions
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H index a7a0ef6b7..826ac93b9 100644 --- a/src/include/kernel/syscalls.H +++ b/src/include/kernel/syscalls.H @@ -6,6 +6,9 @@ namespace Systemcalls enum SysCalls { TASK_YIELD = 0, + TASK_START, + TASK_END, + TASK_GETTID, SYSCALL_MAX }; diff --git a/src/include/kernel/task.H b/src/include/kernel/task.H index d9256c365..4cd19bd04 100644 --- a/src/include/kernel/task.H +++ b/src/include/kernel/task.H @@ -23,4 +23,6 @@ struct task_t task_t* next; }; +enum { TASK_DEFAULT_STACK_SIZE = 4 }; + #endif diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H index 34267324c..2bdb39c16 100644 --- a/src/include/kernel/taskmgr.H +++ b/src/include/kernel/taskmgr.H @@ -10,15 +10,14 @@ class TaskManager static void setCurrentTask(task_t* t); typedef void(*task_fn_t)(void*); + static task_t* createTask(task_fn_t, void*); friend class CpuManager; - friend class Kernel; protected: TaskManager(); ~TaskManager() {}; static task_t* createIdleTask(); - static task_t* createTask(task_fn_t, void*); private: tid_t getNextTid(); diff --git a/src/include/sys/syscall.h b/src/include/sys/syscall.h index b418b5d15..36f84a51f 100644 --- a/src/include/sys/syscall.h +++ b/src/include/sys/syscall.h @@ -19,7 +19,7 @@ void* _syscall7(uint64_t, void*, void*, void*, void*, void*, void*, void*); #ifdef __cplusplus } +#include <kernel/syscalls.H> #endif -#include <kernel/syscalls.H> #endif diff --git a/src/include/sys/task.h b/src/include/sys/task.h new file mode 100644 index 000000000..84ddb10f9 --- /dev/null +++ b/src/include/sys/task.h @@ -0,0 +1,20 @@ +#ifndef __SYS_TASK_H +#define __SYS_TASK_H + +#include <sys/syscall.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +void task_yield(); +int task_create(void(*)(void*), void*); +void task_end(); + +uint64_t task_gettid(); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 9cabeebd3..b993bf222 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -5,6 +5,7 @@ #include <kernel/task.H> #include <kernel/syscalls.H> #include <kernel/console.H> +#include <kernel/pagemgr.H> extern "C" void kernel_execute_decrementer() @@ -22,10 +23,16 @@ namespace Systemcalls { typedef void(*syscall)(task_t*); void TaskYield(task_t*); + void TaskStart(task_t*); + void TaskEnd(task_t*); + void TaskGettid(task_t*); syscall syscalls[] = { &TaskYield, + &TaskStart, + &TaskEnd, + &TaskGettid, }; }; @@ -48,6 +55,18 @@ void kernel_execute_systemcall() } } +#define TASK_GETARGN(t, n) (t->context.gprs[n+4]) +#define TASK_GETARG0(t) (TASK_GETARGN(t,0)) +#define TASK_GETARG1(t) (TASK_GETARGN(t,1)) +#define TASK_GETARG2(t) (TASK_GETARGN(t,2)) +#define TASK_GETARG3(t) (TASK_GETARGN(t,3)) +#define TASK_GETARG4(t) (TASK_GETARGN(t,4)) +#define TASK_GETARG5(t) (TASK_GETARGN(t,5)) +#define TASK_GETARG6(t) (TASK_GETARGN(t,6)) +#define TASK_GETARG7(t) (TASK_GETARGN(t,7)) + +#define TASK_SETRTN(t, n) (t->context.gprs[3] = (n)) + namespace Systemcalls { void TaskYield(task_t* t) @@ -56,4 +75,32 @@ namespace Systemcalls s->returnRunnable(); s->setNextRunnable(); } + + void TaskStart(task_t* t) + { + task_t* newTask = + TaskManager::createTask((TaskManager::task_fn_t)TASK_GETARG0(t), + (void*)TASK_GETARG1(t)); + newTask->cpu = t->cpu; + t->cpu->scheduler->addTask(newTask); + + TASK_SETRTN(t, newTask->tid); + } + + void TaskEnd(task_t* t) + { + // Make sure task pointers are updated before we delete this task. + t->cpu->scheduler->setNextRunnable(); + + // TODO: Deal with join. + + // Clean up task memory. + PageManager::freePage(t->context.stack_ptr, TASK_DEFAULT_STACK_SIZE); + delete t; + } + + void TaskGettid(task_t* t) + { + TASK_SETRTN(t, t->tid); + } }; diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C index fabb70cde..d060b0029 100644 --- a/src/kernel/taskmgr.C +++ b/src/kernel/taskmgr.C @@ -66,7 +66,8 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t, // Setup stack. if (withStack) { - task->context.stack_ptr = PageManager::allocatePage(4); + task->context.stack_ptr = + PageManager::allocatePage(TASK_DEFAULT_STACK_SIZE); task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + 16320; } else diff --git a/src/lib/makefile b/src/lib/makefile index 9ea27377e..1071dc75e 100644 --- a/src/lib/makefile +++ b/src/lib/makefile @@ -1,7 +1,8 @@ OBJDIR = ../../obj include ../../config.mk -OBJS = string.o stdlib.o syscall_stub.o +OBJS = string.o stdlib.o +OBJS += syscall_stub.o syscall_task.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) all: ${OBJECTS} diff --git a/src/lib/syscall_task.C b/src/lib/syscall_task.C new file mode 100644 index 000000000..bfd522933 --- /dev/null +++ b/src/lib/syscall_task.C @@ -0,0 +1,26 @@ +#include <sys/task.h> +#include <kernel/task.H> + +using namespace Systemcalls; + +void task_yield() +{ + _syscall0(TASK_YIELD); + return; +} + +int task_create(void(*fn)(void*), void* ptr) +{ + return (int64_t) _syscall2(TASK_START, (void*)fn, ptr); +} + +void task_end() +{ + _syscall0(TASK_END); // no return. + return; +} + +uint64_t task_gettid() +{ + return (uint64_t)_syscall0(TASK_GETTID); +} diff --git a/src/sys/init/init_main.C b/src/sys/init/init_main.C index e2447bc3f..8be5ae6c3 100644 --- a/src/sys/init/init_main.C +++ b/src/sys/init/init_main.C @@ -1,5 +1,12 @@ #include <kernel/console.H> // TODO : Remove this. -#include <sys/syscall.h> // TODO : Remove this. + +#include <sys/task.h> + +void init_child(void* unused) +{ + printk("Here I am %d\n", task_gettid()); + task_end(); +} void init_main(void* unused) { @@ -7,7 +14,8 @@ void init_main(void* unused) while(1) { - _syscall0(Systemcalls::TASK_YIELD); - for (volatile int i = 0 ; i < 100000; i++); + int t = task_create(&init_child, NULL); + printk("Created child %d\n", t); + for (volatile int i = 0 ; i < 10000000; i++); } } |