From 4962a22309cd7e3586aa57817689b18d67ca71c7 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Mon, 3 Oct 2011 16:12:51 -0500 Subject: Support task_wait / task_wait_tid syscalls: - Add task_end2 syscall to allow pthread_exit-like retval. - Add/maintain task states. - Create task parent/child tracking tree. - Add task_detach function. - Implement wait syscalls. Make task_exec caller the parent of spawned task: Previously the task_exec call caused a message to the VFS task, which called task_create and returned the tid in response to the message. This causes the parent of the spawned task to appear to be the VFS task. Modify task_exec / VFS handling to instead return the entry point address on the message and have task_exec call task_create directly itself. Change-Id: I6b6796f45875de37b1ab01e7596639b073820b95 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/443 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell Reviewed-by: Andrew J. Geissler --- src/lib/syscall_stub.S | 37 +++++++++++++++++++++++++++-------- src/lib/syscall_task.C | 53 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 75 insertions(+), 15 deletions(-) (limited to 'src/lib') diff --git a/src/lib/syscall_stub.S b/src/lib/syscall_stub.S index aca533338..6c839346c 100644 --- a/src/lib/syscall_stub.S +++ b/src/lib/syscall_stub.S @@ -1,24 +1,24 @@ # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. -# +# # $Source: src/lib/syscall_stub.S $ -# +# # IBM CONFIDENTIAL -# +# # COPYRIGHT International Business Machines Corp. 2010 - 2011 -# +# # p1 -# +# # Object Code Only (OCO) source materials # Licensed Internal Code Source Materials # IBM HostBoot Licensed Internal Code -# +# # The source code for this program is not published or other- # wise divested of its trade secrets, irrespective of what has # been deposited with the U.S. Copyright Office. -# +# # Origin: 30 -# +# # IBM_PROLOG_END .section .text @@ -41,3 +41,24 @@ _syscall6: _syscall7: sc blr + +.global _syscall0_nr +.global _syscall1_nr +.global _syscall2_nr +.global _syscall3_nr +.global _syscall4_nr +.global _syscall5_nr +.global _syscall6_nr +.global _syscall7_nr + +_syscall0_nr: +_syscall1_nr: +_syscall2_nr: +_syscall3_nr: +_syscall4_nr: +_syscall5_nr: +_syscall6_nr: +_syscall7_nr: + sc +1: + b 1b diff --git a/src/lib/syscall_task.C b/src/lib/syscall_task.C index 38b8adee4..a00b779f7 100644 --- a/src/lib/syscall_task.C +++ b/src/lib/syscall_task.C @@ -49,8 +49,12 @@ tid_t task_create(void(*fn)(void*), void* ptr) void task_end() { - _syscall0(TASK_END); // no return. - return; + _syscall1_nr(TASK_END, NULL); // no return. +} + +void task_end2(void* retval) +{ + _syscall1_nr(TASK_END, retval); // no return. } tid_t task_gettid() @@ -69,8 +73,8 @@ cpuid_t task_getcpuid() tid_t task_exec(const char* file, void* ptr) { - // The VFS process is responsible for finding the module and creating the - // new process. So, we send a message over to that process. + // The VFS process is responsible for finding the module and entry point + // address, so we send a message over to that process. tid_t child = 0; int rc = 0; @@ -80,7 +84,6 @@ tid_t task_exec(const char* file, void* ptr) msg_t* msg = msg_allocate(); msg->type = VFS_MSG_EXEC; msg->data[0] = (uint64_t) file; - msg->data[1] = (uint64_t) ptr; if (vfsQ) { msg_sendrecv(vfsQ, msg); @@ -93,8 +96,17 @@ tid_t task_exec(const char* file, void* ptr) if (0 == rc) { - // Get child ID from message data 0. - child = (tid_t) msg->data[0]; + // Get fn ptr or error from message data 0. + int64_t value = *reinterpret_cast(&msg->data[0]); + if (value < 0) + { + child = value; + } + else + { + child = task_create(reinterpret_cast(msg->data[0]), + ptr); + } } else { @@ -129,3 +141,30 @@ void task_affinity_migrate_to_master() { _syscall0(TASK_MIGRATE_TO_MASTER); } + +void task_detach() +{ + // Get task structure. + register task_t* task; + asm volatile("mr %0, 13" : "=r"(task)); + + task->detached = true; + // This does not need any sync instruction because the setting is + // only used by the kernel and it requires a context-sync operation + // to enter kernel mode. +} + +tid_t task_wait_tid(tid_t tid, int* status, void** retval) +{ + return static_cast( + reinterpret_cast( + _syscall3(TASK_WAIT,(void*)tid,status,retval))); +} + +tid_t task_wait(int* status, void** retval) +{ + return static_cast( + reinterpret_cast( + _syscall3(TASK_WAIT,(void*)-1,status,retval))); +} + -- cgit v1.2.1