mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 23:53:55 +00:00
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:
committed by
Norman Feske
parent
7fef0ba931
commit
a99193ad90
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
25
base-codezero/src/base/thread/thread_bootstrap.cc
Normal file
25
base-codezero/src/base/thread/thread_bootstrap.cc
Normal 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 */
|
||||
}
|
@ -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()
|
||||
|
@ -42,7 +42,7 @@ int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no)
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_stack(&exregs, (unsigned long)sp);
|
||||
exregs_set_pc (&exregs, (unsigned long)ip);
|
||||
exregs_set_pager(&exregs, pager.tid);
|
||||
exregs_set_pager(&exregs, pager);
|
||||
exregs_set_utcb (&exregs, _utcb);
|
||||
|
||||
int ret = l4_exchange_registers(&exregs, _tid);
|
||||
|
@ -105,12 +105,14 @@ void Thread_base::start()
|
||||
_tid.pt = new(platform()->core_mem_alloc()) Platform_thread(_context->name);
|
||||
|
||||
_tid.l4id = create_thread(1, &_context->stack[-4], (void *)&_thread_start);
|
||||
if (_tid.l4id.tid < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id.tid);
|
||||
|
||||
if (_tid.l4id < 0)
|
||||
PERR("create_thread returned %d", _tid.l4id);
|
||||
|
||||
if (verbose_thread_start)
|
||||
printf("core started local thread \"%s\" with ID %d\n",
|
||||
_context->name, _tid.l4id.tid);
|
||||
_context->name, _tid.l4id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,9 +59,19 @@ extern "C" int printf(const char *format, ...)
|
||||
** Startup-code helpers **
|
||||
**************************/
|
||||
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
static void main_thread_bootstrap()
|
||||
{
|
||||
Codezero::__l4_init();
|
||||
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
|
||||
Codezero::l4_mutex_init(&main_thread_running_lock);
|
||||
Codezero::l4_mutex_lock(&main_thread_running_lock); /* block on first mutex lock */
|
||||
}
|
||||
|
||||
#endif /* _PLATFORM___MAIN_HELPER_H_ */
|
||||
|
Reference in New Issue
Block a user