diff --git a/base/src/test/thread/main.cc b/base/src/test/thread/main.cc
index 8a83f52b11..bdb0ab491e 100644
--- a/base/src/test/thread/main.cc
+++ b/base/src/test/thread/main.cc
@@ -1,6 +1,7 @@
/*
- * \brief Testing thread environment of a main thread
+ * \brief Testing thread library
* \author Alexander Boettcher
+ * \author Christian Helmuth
* \date 2013-12-13
*/
@@ -15,13 +16,54 @@
#include
#include
+
using namespace Genode;
-int main(int argc, char **argv)
+
+template
+struct Helper : Thread<0x2000>
+{
+ void *child[CHILDREN];
+
+ Helper() : Thread<0x2000>("helper") { }
+
+ void *context() const { return _context; }
+
+ void entry()
+ {
+ Helper helper[CHILDREN];
+
+ for (unsigned i = 0; i < CHILDREN; ++i)
+ child[i] = helper[i].context();
+ }
+};
+
+
+static void test_context_alloc()
+{
+ /*
+ * Create HELPER threads, which concurrently create CHILDREN threads each.
+ * This most likely triggers any race in the thread-context allocation.
+ */
+ enum { HELPER = 10, CHILDREN = 10 };
+
+ Helper helper[HELPER];
+
+ for (unsigned i = 0; i < HELPER; ++i) helper[i].start();
+ for (unsigned i = 0; i < HELPER; ++i) helper[i].join();
+
+ if (0)
+ for (unsigned i = 0; i < HELPER; ++i)
+ for (unsigned j = 0; j < CHILDREN; ++j)
+ printf("%p [%d.%d]\n", helper[i].child[j], i, j);
+}
+
+
+static void test_main_thread()
{
/* check wether my thread object exists */
Thread_base * myself = Genode::Thread_base::myself();
- if (!myself) { return -1; }
+ if (!myself) { throw -1; }
printf("thread base %p\n", myself);
/* check wether my stack is inside the first context region */
@@ -30,18 +72,28 @@ int main(int argc, char **argv)
addr_t const context_top = context_base + context_size;
addr_t const stack_top = (addr_t)myself->stack_top();
addr_t const stack_base = (addr_t)myself->stack_base();
- if (stack_top <= context_base) { return -2; }
- if (stack_top > context_top) { return -3; }
- if (stack_base >= context_top) { return -4; }
- if (stack_base < context_base) { return -5; }
+ if (stack_top <= context_base) { throw -2; }
+ if (stack_top > context_top) { throw -3; }
+ if (stack_base >= context_top) { throw -4; }
+ if (stack_base < context_base) { throw -5; }
printf("thread stack top %p\n", myself->stack_top());
printf("thread stack bottom %p\n", myself->stack_base());
/* check wether my stack pointer is inside my stack */
unsigned dummy = 0;
addr_t const sp = (addr_t)&dummy;
- if (sp >= stack_top) { return -6; }
- if (sp < stack_base) { return -7; }
+ if (sp >= stack_top) { throw -6; }
+ if (sp < stack_base) { throw -7; }
printf("thread stack pointer %p\n", (void *)sp);
- return 0;
+}
+
+
+int main()
+{
+ try {
+ test_main_thread();
+ test_context_alloc();
+ } catch (int error) {
+ return error;
+ }
}