From 087582a964ae4832d4cf6d4ff260cb8739a0e96f Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 5 Nov 2012 17:01:43 +0100 Subject: [PATCH] Linux: Synchronize thread startup The thread ID reported to core was not always initialized prior the RPC call. The 'startup_lock' ensures that the thread is completely initialized before this information gets propagated. --- base-linux/src/base/thread/thread_linux.cc | 29 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/base-linux/src/base/thread/thread_linux.cc b/base-linux/src/base/thread/thread_linux.cc index 5625c3b5f9..7f72dd1212 100644 --- a/base-linux/src/base/thread/thread_linux.cc +++ b/base-linux/src/base/thread/thread_linux.cc @@ -27,13 +27,20 @@ using namespace Genode; static void empty_signal_handler(int) { } +static Lock &startup_lock() +{ + static Lock lock(Lock::LOCKED); + return lock; +} + + /** * Signal handler for killing the thread */ static void thread_exit_signal_handler(int) { lx_exit(0); } -static void thread_start(void *) +static void thread_start(void *arg) { /* * Set signal handler such that canceled system calls get not @@ -46,6 +53,16 @@ static void thread_start(void *) */ lx_sigaction(LX_SIGCHLD, (void (*)(int))1); + Thread_base *thread = (Thread_base *)arg; + + /* inform core about the new thread and process ID of the new thread */ + Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session()); + if (cpu) + cpu->thread_id(thread->cap(), thread->tid().pid, thread->tid().tid); + + /* wakeup 'start' function */ + startup_lock().unlock(); + Thread_base::myself()->entry(); sleep_forever(); } @@ -90,6 +107,10 @@ void Thread_base::_deinit_platform_thread() void Thread_base::start() { + /* synchronize calls of the 'start' function */ + static Lock lock; + Lock::Guard guard(lock); + /* * The first time we enter this code path, the 'start' function is * called by the main thread as there cannot exist other threads @@ -107,10 +128,8 @@ void Thread_base::start() _tid.tid = lx_create_thread(thread_start, thread_sp, this); _tid.pid = lx_getpid(); - /* inform core about the new thread and process ID of the new thread */ - Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session()); - if (cpu) - cpu->thread_id(_thread_cap, _tid.pid, _tid.tid); + /* wait until the 'thread_start' function got entered */ + startup_lock().lock(); }