summaryrefslogtreecommitdiffstats
path: root/src/usr/testcore
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-10-03 16:12:51 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-10-24 13:33:20 -0500
commit4962a22309cd7e3586aa57817689b18d67ca71c7 (patch)
tree2bfd610d6ed048f7d4a35717211eca06b15d1f69 /src/usr/testcore
parent21185b30cd99a00f01e15edba28402cdc00de1d1 (diff)
downloadtalos-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.H177
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;
+ }
+};
OpenPOWER on IntegriCloud