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; + } }