diff options
-rw-r--r-- | src/include/sys/task.h | 8 | ||||
-rw-r--r-- | src/kernel/taskmgr.C | 9 |
2 files changed, 14 insertions, 3 deletions
diff --git a/src/include/sys/task.h b/src/include/sys/task.h index 265f175fb..901f938ea 100644 --- a/src/include/sys/task.h +++ b/src/include/sys/task.h @@ -36,9 +36,11 @@ tid_t task_create(void(*start_routine)(void*), void* arg); * * See POSIX pthread_exit. * - * @note A thread must call task_end when it wishes to exit. It is not - * acceptable to simply return from the 'start_routine' and may result - * in unexpected behavior. + * @note A task must call task_end when it wishes to exit. If a task were + * to simply return from its entry point function, the kernel sets up + * the initial task structure with the link-register pointing to this + * function. Therefore, returning from the entry point function will + * also cause the task to end cleanly using this function. */ void task_end(); diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C index 8225b7da3..0573bab7d 100644 --- a/src/kernel/taskmgr.C +++ b/src/kernel/taskmgr.C @@ -3,8 +3,10 @@ #include <kernel/task.H> #include <kernel/pagemgr.H> #include <kernel/cpumgr.H> +#include <sys/task.h> #include <arch/ppc.H> #include <string.h> +#include <limits.h> void TaskManager::idleTaskLoop(void* unused) { @@ -60,6 +62,11 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t, task->context.nip = (void*) ((uint64_t*) t)[0]; task->context.gprs[2] = ((uint64_t*)t)[1]; + // Set up LR to be the entry point for task_end in case a task + // 'returns' from its entry point. By the Power ABI, the entry + // point address is in (func_ptr)[0]. + task->context.lr = reinterpret_cast<uint64_t*>(&task_end)[0]; + // Set up GRP[13] as task structure reserved. task->context.gprs[13] = (uint64_t)task; @@ -71,6 +78,8 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t, { task->context.stack_ptr = PageManager::allocatePage(TASK_DEFAULT_STACK_SIZE); + memset(task->context.stack_ptr, '\0', + TASK_DEFAULT_STACK_SIZE * PAGE_SIZE); task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + 16320; } else |