Rework the internal lock interface

With this patch, the 'futex' syscall gets used for blocking and unblocking
of threads in the Linux-specific lock implementation.

The 'Native_thread_id' type, which was previously used in the
lock-internal 'Applicant' class to identify a thread to be woken up,
was not suitable anymore for implementing this change. With this patch,
the 'Thread_base*' type gets used instead, which also has the positive
effect of making the public 'cancelable_lock.h' header file
platform-independent.

Fixes #646.
This commit is contained in:
Christian Prochaska
2013-02-25 21:18:26 +01:00
committed by Norman Feske
parent 7fef0ba931
commit a99193ad90
36 changed files with 496 additions and 330 deletions

View File

@ -150,11 +150,11 @@ void Ipc_pager::reply_and_wait_for_fault()
int ret = l4_map((void *)_reply_mapping.from_phys(),
(void *)_reply_mapping.to_virt(),
_reply_mapping.num_pages(), flags, _last.tid);
_reply_mapping.num_pages(), flags, _last);
/* wake up faulter if mapping succeeded */
if (ret < 0)
PERR("l4_map returned %d, putting thread %d to sleep", ret, _last.tid);
PERR("l4_map returned %d, putting thread %d to sleep", ret, _last);
else
acknowledge_wakeup();
@ -166,7 +166,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup()
{
enum { SUCCESS = 0 };
l4_set_sender(_last.tid);
l4_set_sender(_last);
l4_ipc_return(SUCCESS);
}

View File

@ -22,7 +22,8 @@
#include <codezero/syscalls.h>
static Codezero::l4_mutex main_running_lock = { -1 };
extern Genode::Native_thread_id main_thread_tid;
extern Codezero::l4_mutex main_thread_running_lock;
static inline void thread_yield()
@ -31,58 +32,30 @@ static inline void thread_yield()
}
static inline bool thread_id_valid(Genode::Native_thread_id tid)
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
return tid.tid != Codezero::NILTHREAD;
}
static inline bool thread_check_stopped_and_restart(Genode::Native_thread_id tid)
{
if (!thread_id_valid(tid))
return false;
Codezero::l4_mutex_unlock(tid.running_lock);
Codezero::l4_mutex *running_lock = thread_base ?
thread_base->utcb()->running_lock() :
&main_thread_running_lock;
Codezero::l4_mutex_unlock(running_lock);
return true;
}
static inline Genode::Native_thread_id thread_get_my_native_id()
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
using namespace Genode;
Codezero::l4_mutex *running_lock = 0;
/* obtain pointer to running lock of calling thread */
if (Thread_base::myself())
running_lock = Thread_base::myself()->utcb()->running_lock();
else {
running_lock = &main_running_lock;
if (running_lock->lock == -1) {
Codezero::l4_mutex_init(running_lock);
Codezero::l4_mutex_lock(running_lock); /* block on first mutex lock */
}
}
return Genode::Native_thread_id(Codezero::thread_myself(), running_lock);
}
static inline Genode::Native_thread_id thread_invalid_id()
{
return Genode::Native_thread_id(Codezero::NILTHREAD, 0);
}
static inline void thread_switch_to(Genode::Native_thread_id tid)
{
if (thread_id_valid(tid))
Codezero::l4_thread_switch(tid.tid);
Genode::Native_thread_id tid = thread_base ?
thread_base->tid().l4id :
main_thread_tid;
Codezero::l4_thread_switch(tid);
}
static inline void thread_stop_myself()
{
Genode::Native_thread_id myself = thread_get_my_native_id();
Codezero::l4_mutex_lock(myself.running_lock);
Genode::Thread_base *myself = Genode::Thread_base::myself();
Codezero::l4_mutex *running_lock = myself ?
myself->utcb()->running_lock() :
&main_thread_running_lock;
Codezero::l4_mutex_lock(running_lock);
}

View File

@ -0,0 +1,25 @@
/*
* \brief Thread bootstrap code
* \author Christian Prochaska
* \date 2013-02-15
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
/* Codezero includes */
#include <codezero/syscalls.h>
void Genode::Thread_base::_thread_bootstrap()
{
Codezero::l4_mutex_init(utcb()->running_lock());
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
}

View File

@ -39,11 +39,7 @@ void Thread_base::_thread_start()
** Thread base **
*****************/
void Thread_base::_init_platform_thread()
{
Codezero::l4_mutex_init(utcb()->running_lock());
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
}
void Thread_base::_init_platform_thread() { }
void Thread_base::_deinit_platform_thread()