diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-10-03 16:12:51 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-10-24 13:33:20 -0500 |
commit | 4962a22309cd7e3586aa57817689b18d67ca71c7 (patch) | |
tree | 2bfd610d6ed048f7d4a35717211eca06b15d1f69 /src/usr/testcore | |
parent | 21185b30cd99a00f01e15edba28402cdc00de1d1 (diff) | |
download | talos-hostboot-4962a22309cd7e3586aa57817689b18d67ca71c7.tar.gz talos-hostboot-4962a22309cd7e3586aa57817689b18d67ca71c7.zip |
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 <dcrowell@us.ibm.com>
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Diffstat (limited to 'src/usr/testcore')
-rw-r--r-- | src/usr/testcore/kernel/taskwaittest.H | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/usr/testcore/kernel/taskwaittest.H b/src/usr/testcore/kernel/taskwaittest.H new file mode 100644 index 000000000..00ec0990f --- /dev/null +++ b/src/usr/testcore/kernel/taskwaittest.H @@ -0,0 +1,177 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/testcore/kernel/tasktest.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 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 +/** @file tasktest.H + * @brief Test cases for task interfaces. + */ + +#include <cxxtest/TestSuite.H> +#include <sys/task.h> +#include <sys/time.h> +#include <errno.h> +#include <kernel/console.H> +#include <kernel/timemgr.H> + +#define NS_PER_SEC (1000000ull) +#define TEN_CTX_SWITCHES ((NS_PER_SEC/TimeManager::TIMESLICE_PER_SEC)*10) + +class TaskWaitTest : public CxxTest::TestSuite +{ + public: + + void testWaitAfterChildExit() + { + int status = 0x1234; + tid_t child = task_create(&WaitSomeTime, NULL); + WaitSomeLongerTime(NULL); + + // Join with that child task to clean it up. + if (child != task_wait_tid(child, &status, NULL)) + { + TS_FAIL("Failed to join with test-case child."); + } + if (status != TASK_STATUS_EXITED_CLEAN) + { + TS_FAIL("Task status is incorrect after wait."); + } + } + + void testWaitBeforeChildExit() + { + tid_t child = task_create(&WaitSomeLongerTime, NULL); + WaitSomeTime(NULL); + + // Join with that child task to clean it up. + if (child != task_wait_tid(child, NULL, NULL)) + { + TS_FAIL("Failed to join with test-case child."); + } + } + + void testWaitOnTwoChildren() + { + tid_t child[2] = { task_create(&WaitSomeTime, NULL), + task_create(&WaitSomeTime, NULL) }; + + tid_t completed = 0; + + completed = task_wait(NULL, NULL); + if ((completed != child[0]) && (completed != child[1])) + { + TS_FAIL("Different child returned than one waited on."); + } + + completed = task_wait(NULL, NULL); + if ((completed != child[0]) && (completed != child[1])) + { + TS_FAIL("Different child returned than one waited on."); + } + } + + void testWaitOnGrandchild() + { + tid_t child = task_create(&TaskWithChild, NULL); + void* retval; + + task_wait_tid(child, NULL, &retval); + + tid_t grandchild = static_cast<tid_t>( + reinterpret_cast<uint64_t>(retval)); + + if (grandchild != task_wait_tid(grandchild, NULL, NULL)) + { + TS_FAIL("Grand-child task was not joined with."); + } + } + + void testWaitOnCrash() + { + int status = 1234; + tid_t child = task_create(&TaskThatCrashes, NULL); + + task_wait_tid(child, &status, NULL); + + if (status != TASK_STATUS_CRASHED) + { + TS_FAIL("Task wait status is incorrect."); + } + } + + void testWaitDeadlock() + { + // Check for any thread when we don't have a child. + if (((tid_t)-EDEADLK) != task_wait(NULL, NULL)) + { + TS_FAIL("Deadlock condition not detected."); + } + + // Check for waiting on the wrong task. + tid_t child = task_create(&WaitSomeTime, NULL); + if (((tid_t)-EDEADLK) != task_wait_tid(0, NULL, NULL)) + { + TS_FAIL("Deadlock condition not detected."); + } + + // Join with that child task to clean it up. + if (child != task_wait_tid(child, NULL, NULL)) + { + TS_FAIL("Failed to join with test-case child."); + } + } + + void testWaitAddrFault() + { + if (((tid_t)-EFAULT) != task_wait((int*)4, NULL)) + { + TS_FAIL("Bad address on status not caught."); + } + + if (((tid_t)-EFAULT) != task_wait(NULL, (void**)4)) + { + TS_FAIL("Bad address on ret-val not caught."); + } + } + + static void WaitSomeTime(void* retval) + { + nanosleep(0,TEN_CTX_SWITCHES); + if (retval) task_end2(retval); + } + + static void WaitSomeLongerTime(void* retval) + { + nanosleep(0, 2*TEN_CTX_SWITCHES); + if (retval) task_end2(retval); + } + + static void TaskWithChild(void* unused) + { + tid_t child = task_create(&WaitSomeTime, NULL); + task_end2(reinterpret_cast<void*>(child)); + } + + static void TaskThatCrashes(void* unused) + { + printk("Test case: Expect to see uncaught exception!"); + *(int64_t*)(0) = 0xDEADC0DE; + } +}; |