summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/sys/task.h8
-rw-r--r--src/kernel/taskmgr.C9
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
OpenPOWER on IntegriCloud