mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-20 08:03:56 +00:00
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.
This commit is contained in:
@ -27,13 +27,20 @@ using namespace Genode;
|
|||||||
static void empty_signal_handler(int) { }
|
static void empty_signal_handler(int) { }
|
||||||
|
|
||||||
|
|
||||||
|
static Lock &startup_lock()
|
||||||
|
{
|
||||||
|
static Lock lock(Lock::LOCKED);
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signal handler for killing the thread
|
* Signal handler for killing the thread
|
||||||
*/
|
*/
|
||||||
static void thread_exit_signal_handler(int) { lx_exit(0); }
|
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
|
* 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);
|
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<Linux_cpu_session *>(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();
|
Thread_base::myself()->entry();
|
||||||
sleep_forever();
|
sleep_forever();
|
||||||
}
|
}
|
||||||
@ -90,6 +107,10 @@ void Thread_base::_deinit_platform_thread()
|
|||||||
|
|
||||||
void Thread_base::start()
|
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
|
* The first time we enter this code path, the 'start' function is
|
||||||
* called by the main thread as there cannot exist other threads
|
* 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.tid = lx_create_thread(thread_start, thread_sp, this);
|
||||||
_tid.pid = lx_getpid();
|
_tid.pid = lx_getpid();
|
||||||
|
|
||||||
/* inform core about the new thread and process ID of the new thread */
|
/* wait until the 'thread_start' function got entered */
|
||||||
Linux_cpu_session *cpu = dynamic_cast<Linux_cpu_session *>(env()->cpu_session());
|
startup_lock().lock();
|
||||||
if (cpu)
|
|
||||||
cpu->thread_id(_thread_cap, _tid.pid, _tid.tid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user