mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
hw: get rid of Kernel::current_thread_id
Every thread receives a startup message from its creator through the initial state of its userland thread-context. The thread-startup code remembers the kernel name of the new thread by reading this message before the userland thread-context gets polluted. This way, Kernel::current_thread_id becomes unnecessary. fix #953
This commit is contained in:
parent
b5e92653bf
commit
b694045bd9
@ -28,8 +28,8 @@ namespace Genode
|
|||||||
|
|
||||||
struct Native_thread
|
struct Native_thread
|
||||||
{
|
{
|
||||||
Native_thread_id tid;
|
Platform_thread * platform_thread;
|
||||||
Platform_thread *pt;
|
Native_thread_id thread_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int Native_connection_state;
|
typedef int Native_connection_state;
|
||||||
@ -38,13 +38,12 @@ namespace Genode
|
|||||||
enum { MIN_MAPPING_SIZE_LOG2 = 12 };
|
enum { MIN_MAPPING_SIZE_LOG2 = 12 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get kernel-object identifier of the current thread
|
* Return kernel thread-name of the caller
|
||||||
*/
|
*/
|
||||||
inline Native_thread_id thread_get_my_native_id()
|
Native_thread_id thread_get_my_native_id();
|
||||||
{ return Kernel::current_thread_id(); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the thread ID, wich is handled as invalid by the kernel
|
* Return an invalid kernel thread-name
|
||||||
*/
|
*/
|
||||||
inline Native_thread_id thread_invalid_id() { return 0; }
|
inline Native_thread_id thread_invalid_id() { return 0; }
|
||||||
|
|
||||||
@ -59,8 +58,9 @@ namespace Genode
|
|||||||
struct Type
|
struct Type
|
||||||
{
|
{
|
||||||
enum Id {
|
enum Id {
|
||||||
INVALID = 0,
|
INVALID = 0,
|
||||||
IPC = 1,
|
STARTUP = 1,
|
||||||
|
IPC = 2,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,48 +78,14 @@ namespace Genode
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a userland-thread-context region
|
* Message that is communicated from a thread creator to the new thread
|
||||||
*/
|
*/
|
||||||
struct Native_utcb
|
class Startup_msg;
|
||||||
{
|
|
||||||
union {
|
|
||||||
uint8_t data[1 << MIN_MAPPING_SIZE_LOG2];
|
|
||||||
Msg msg;
|
|
||||||
Ipc_msg ipc_msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
void call_wait_for_request(void * & buf_base, size_t & buf_size)
|
/**
|
||||||
{
|
* Memory region that is exclusive to every thread and known by the kernel
|
||||||
msg.type = Msg::Type::INVALID;
|
*/
|
||||||
buf_base = base();
|
struct Native_utcb;
|
||||||
buf_size = size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void call_request_and_wait(void * & msg_base, size_t & msg_size,
|
|
||||||
void * & buf_base, size_t & buf_size)
|
|
||||||
{
|
|
||||||
msg.type = Msg::Type::IPC;
|
|
||||||
msg_base = ipc_msg_base();
|
|
||||||
msg_size = ipc_msg_size();
|
|
||||||
buf_base = base();
|
|
||||||
buf_size = size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void call_reply(void * & msg_base, size_t & msg_size)
|
|
||||||
{
|
|
||||||
msg.type = Msg::Type::IPC;
|
|
||||||
msg_base = ipc_msg_base();
|
|
||||||
msg_size = ipc_msg_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() { return sizeof(data) / sizeof(data[0]); }
|
|
||||||
void * base() { return &data; }
|
|
||||||
addr_t top() { return (addr_t)base() + size(); }
|
|
||||||
void * ipc_msg_base() { return &ipc_msg; }
|
|
||||||
size_t ipc_msg_size() { return ipc_msg_header_size() + ipc_msg.size; }
|
|
||||||
size_t ipc_msg_max_size() { return top() - (addr_t)&ipc_msg; }
|
|
||||||
size_t ipc_msg_header_size() { return (addr_t)ipc_msg.data - (addr_t)&ipc_msg; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Cap_dst_policy
|
struct Cap_dst_policy
|
||||||
{
|
{
|
||||||
@ -145,7 +111,7 @@ namespace Genode
|
|||||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A coherent address region
|
* Coherent address region
|
||||||
*/
|
*/
|
||||||
struct Native_region
|
struct Native_region
|
||||||
{
|
{
|
||||||
@ -170,5 +136,76 @@ namespace Genode
|
|||||||
struct Native_pd_args { };
|
struct Native_pd_args { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Genode::Startup_msg : public Msg
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Native_thread_id _thread_id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set-up valid startup message
|
||||||
|
*
|
||||||
|
* \param thread_id kernel name of the thread that is started
|
||||||
|
*/
|
||||||
|
void init(Native_thread_id const thread_id)
|
||||||
|
{
|
||||||
|
_thread_id = thread_id;
|
||||||
|
type = Msg::Type::STARTUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return kernel name of started thread message-type-save
|
||||||
|
*/
|
||||||
|
Native_thread_id thread_id() const
|
||||||
|
{
|
||||||
|
if (type == Msg::Type::STARTUP) { return _thread_id; }
|
||||||
|
return thread_invalid_id();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Genode::Native_utcb
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
uint8_t data[1 << MIN_MAPPING_SIZE_LOG2];
|
||||||
|
Msg msg;
|
||||||
|
Ipc_msg ipc_msg;
|
||||||
|
Startup_msg startup_msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
void call_wait_for_request(void * & buf_base, size_t & buf_size)
|
||||||
|
{
|
||||||
|
msg.type = Msg::Type::INVALID;
|
||||||
|
buf_base = base();
|
||||||
|
buf_size = size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_request_and_wait(void * & msg_base, size_t & msg_size,
|
||||||
|
void * & buf_base, size_t & buf_size)
|
||||||
|
{
|
||||||
|
msg.type = Msg::Type::IPC;
|
||||||
|
msg_base = ipc_msg_base();
|
||||||
|
msg_size = ipc_msg_size();
|
||||||
|
buf_base = base();
|
||||||
|
buf_size = size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_reply(void * & msg_base, size_t & msg_size)
|
||||||
|
{
|
||||||
|
msg.type = Msg::Type::IPC;
|
||||||
|
msg_base = ipc_msg_base();
|
||||||
|
msg_size = ipc_msg_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() { return sizeof(data) / sizeof(data[0]); }
|
||||||
|
void * base() { return &data; }
|
||||||
|
addr_t top() { return (addr_t)base() + size(); }
|
||||||
|
void * ipc_msg_base() { return &ipc_msg; }
|
||||||
|
size_t ipc_msg_size() { return ipc_msg_header_size() + ipc_msg.size; }
|
||||||
|
size_t ipc_msg_max_size() { return top() - (addr_t)&ipc_msg; }
|
||||||
|
size_t ipc_msg_header_size() { return (addr_t)ipc_msg.data - (addr_t)&ipc_msg; }
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _BASE__NATIVE_TYPES_H_ */
|
#endif /* _BASE__NATIVE_TYPES_H_ */
|
||||||
|
|
||||||
|
@ -43,29 +43,28 @@ namespace Kernel
|
|||||||
START_THREAD = 2,
|
START_THREAD = 2,
|
||||||
PAUSE_THREAD = 3,
|
PAUSE_THREAD = 3,
|
||||||
RESUME_THREAD = 4,
|
RESUME_THREAD = 4,
|
||||||
CURRENT_THREAD_ID = 5,
|
YIELD_THREAD = 5,
|
||||||
YIELD_THREAD = 6,
|
ACCESS_THREAD_REGS = 6,
|
||||||
ACCESS_THREAD_REGS = 7,
|
ROUTE_THREAD_EVENT = 7,
|
||||||
ROUTE_THREAD_EVENT = 8,
|
UPDATE_PD = 8,
|
||||||
UPDATE_PD = 9,
|
UPDATE_REGION = 9,
|
||||||
UPDATE_REGION = 10,
|
NEW_PD = 10,
|
||||||
NEW_PD = 11,
|
KILL_PD = 11,
|
||||||
KILL_PD = 12,
|
REQUEST_AND_WAIT = 12,
|
||||||
REQUEST_AND_WAIT = 13,
|
REPLY = 13,
|
||||||
REPLY = 14,
|
WAIT_FOR_REQUEST = 14,
|
||||||
WAIT_FOR_REQUEST = 15,
|
NEW_SIGNAL_RECEIVER = 15,
|
||||||
NEW_SIGNAL_RECEIVER = 16,
|
NEW_SIGNAL_CONTEXT = 16,
|
||||||
NEW_SIGNAL_CONTEXT = 17,
|
KILL_SIGNAL_CONTEXT = 17,
|
||||||
KILL_SIGNAL_CONTEXT = 18,
|
KILL_SIGNAL_RECEIVER = 18,
|
||||||
KILL_SIGNAL_RECEIVER = 19,
|
SUBMIT_SIGNAL = 19,
|
||||||
SUBMIT_SIGNAL = 20,
|
AWAIT_SIGNAL = 20,
|
||||||
AWAIT_SIGNAL = 21,
|
SIGNAL_PENDING = 21,
|
||||||
SIGNAL_PENDING = 22,
|
ACK_SIGNAL = 22,
|
||||||
ACK_SIGNAL = 23,
|
NEW_VM = 23,
|
||||||
NEW_VM = 24,
|
RUN_VM = 24,
|
||||||
RUN_VM = 25,
|
PAUSE_VM = 25,
|
||||||
PAUSE_VM = 26,
|
PRINT_CHAR = 26,
|
||||||
PRINT_CHAR = 27,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -295,15 +294,6 @@ namespace Kernel
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the thread ID of the current thread
|
|
||||||
*/
|
|
||||||
inline int current_thread_id()
|
|
||||||
{
|
|
||||||
return call(Call_id::CURRENT_THREAD_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set or unset the handler of an event a kernel thread-object triggers
|
* Set or unset the handler of an event a kernel thread-object triggers
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Helper functions for the Lock implementation
|
* \brief Helper functions for the lock implementation
|
||||||
* \author Martin Stein
|
* \author Martin Stein
|
||||||
* \date 2011-01-02
|
* \date 2011-01-02
|
||||||
*/
|
*/
|
||||||
@ -11,55 +11,56 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SRC__BASE__LOCK__LOCK_HELPER_H_
|
#ifndef _LOCK_HELPER_H_
|
||||||
#define _SRC__BASE__LOCK__LOCK_HELPER_H_
|
#define _LOCK_HELPER_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/native_types.h>
|
#include <base/native_types.h>
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
|
|
||||||
|
extern Genode::Native_thread_id _main_thread_id;
|
||||||
extern Genode::Native_thread_id main_thread_tid;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yield CPU to any other thread
|
* Yield execution time-slice of current thread
|
||||||
*/
|
*/
|
||||||
static inline void thread_yield()
|
static inline void thread_yield() { Kernel::yield_thread(); }
|
||||||
{ Kernel::yield_thread(); }
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yield CPU to a specified thread 't'
|
* Return kernel name of thread t
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline Genode::Native_thread_id
|
||||||
thread_switch_to(Genode::Thread_base *thread_base)
|
native_thread_id(Genode::Thread_base * const t)
|
||||||
{
|
{
|
||||||
Genode::Native_thread_id t = thread_base ?
|
return t ? t->tid().thread_id : _main_thread_id;
|
||||||
thread_base->tid().tid :
|
|
||||||
main_thread_tid;
|
|
||||||
Kernel::yield_thread(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume another thread 't' and return if it were paused or not
|
* Yield execution time-slice of current thread to thread t
|
||||||
|
*/
|
||||||
|
static inline void thread_switch_to(Genode::Thread_base * const t)
|
||||||
|
{
|
||||||
|
Kernel::yield_thread(native_thread_id(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resume thread t and return wether t was paused or not
|
||||||
*/
|
*/
|
||||||
static inline bool
|
static inline bool
|
||||||
thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
|
thread_check_stopped_and_restart(Genode::Thread_base * const t)
|
||||||
{
|
{
|
||||||
Genode::Native_thread_id t = thread_base ?
|
return Kernel::resume_thread(native_thread_id(t)) == 0;
|
||||||
thread_base->tid().tid :
|
|
||||||
main_thread_tid;
|
|
||||||
return Kernel::resume_thread(t) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exclude ourselves from CPU scheduling for now
|
* Pause execution of current thread
|
||||||
*/
|
*/
|
||||||
static inline void thread_stop_myself() { Kernel::pause_thread(); }
|
static inline void thread_stop_myself() { Kernel::pause_thread(); }
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SRC__BASE__LOCK__LOCK_HELPER_H_ */
|
#endif /* _LOCK_HELPER_H_ */
|
||||||
|
|
||||||
|
@ -20,5 +20,6 @@
|
|||||||
|
|
||||||
void Genode::Thread_base::_thread_bootstrap()
|
void Genode::Thread_base::_thread_bootstrap()
|
||||||
{
|
{
|
||||||
_tid.tid = Kernel::current_thread_id();
|
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||||
|
_tid.thread_id = utcb->startup_msg.thread_id();
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,20 @@ using namespace Genode;
|
|||||||
|
|
||||||
extern Native_utcb * __initial_sp;
|
extern Native_utcb * __initial_sp;
|
||||||
|
|
||||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||||
|
|
||||||
|
|
||||||
/*****************
|
/*****************
|
||||||
** Thread_base **
|
** Thread_base **
|
||||||
*****************/
|
*****************/
|
||||||
|
|
||||||
|
void Thread_base::_init_platform_thread() { }
|
||||||
|
|
||||||
|
|
||||||
Native_utcb * Thread_base::utcb()
|
Native_utcb * Thread_base::utcb()
|
||||||
{
|
{
|
||||||
/* this is a main thread, so CRT0 provides UTCB through '_main_utcb' */
|
if (this) { return &_context->utcb; }
|
||||||
if (!this) return __initial_sp;
|
return __initial_sp;
|
||||||
|
|
||||||
/* otherwise we have a valid thread base */
|
|
||||||
return &_context->utcb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -47,19 +47,16 @@ void Thread_base::_thread_start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Thread_base::_init_platform_thread() { }
|
|
||||||
|
|
||||||
|
|
||||||
void Thread_base::_deinit_platform_thread()
|
void Thread_base::_deinit_platform_thread()
|
||||||
{
|
{
|
||||||
/* detach UTCB */
|
/* detach userland thread-context */
|
||||||
size_t const size = sizeof(_context->utcb);
|
size_t const size = sizeof(_context->utcb);
|
||||||
addr_t utcb = Context_allocator::addr_to_base(_context) +
|
addr_t utcb = Context_allocator::addr_to_base(_context) +
|
||||||
Native_config::context_virtual_size() - size -
|
Native_config::context_virtual_size() - size -
|
||||||
Native_config::context_area_virtual_base();
|
Native_config::context_area_virtual_base();
|
||||||
env_context_area_rm_session()->detach(utcb);
|
env_context_area_rm_session()->detach(utcb);
|
||||||
|
|
||||||
/* destroy object at the CPU session */
|
/* destroy server object */
|
||||||
env()->cpu_session()->kill_thread(_thread_cap);
|
env()->cpu_session()->kill_thread(_thread_cap);
|
||||||
if (_pager_cap.valid()) {
|
if (_pager_cap.valid()) {
|
||||||
env()->rm_session()->remove_client(_pager_cap);
|
env()->rm_session()->remove_client(_pager_cap);
|
||||||
@ -69,7 +66,7 @@ void Thread_base::_deinit_platform_thread()
|
|||||||
|
|
||||||
void Thread_base::start()
|
void Thread_base::start()
|
||||||
{
|
{
|
||||||
/* create thread at core */
|
/* create server object */
|
||||||
char buf[48];
|
char buf[48];
|
||||||
name(buf, sizeof(buf));
|
name(buf, sizeof(buf));
|
||||||
Cpu_session * cpu = env()->cpu_session();
|
Cpu_session * cpu = env()->cpu_session();
|
||||||
@ -78,11 +75,11 @@ void Thread_base::start()
|
|||||||
/* assign thread to protection domain */
|
/* assign thread to protection domain */
|
||||||
env()->pd_session()->bind_thread(_thread_cap);
|
env()->pd_session()->bind_thread(_thread_cap);
|
||||||
|
|
||||||
/* create new pager object and assign it to the new thread */
|
/* create pager object and assign it to the thread */
|
||||||
_pager_cap = env()->rm_session()->add_client(_thread_cap);
|
_pager_cap = env()->rm_session()->add_client(_thread_cap);
|
||||||
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
|
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
|
||||||
|
|
||||||
/* attach UTCB */
|
/* attach userland thread-context */
|
||||||
try {
|
try {
|
||||||
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
|
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
|
||||||
size_t const size = sizeof(_context->utcb);
|
size_t const size = sizeof(_context->utcb);
|
||||||
@ -91,7 +88,7 @@ void Thread_base::start()
|
|||||||
Native_config::context_area_virtual_base();
|
Native_config::context_area_virtual_base();
|
||||||
env_context_area_rm_session()->attach_at(ds, dst, size);
|
env_context_area_rm_session()->attach_at(ds, dst, size);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
PERR("%s: Failed to attach UTCB", __PRETTY_FUNCTION__);
|
PERR("failed to attach userland thread-context");
|
||||||
sleep_forever();
|
sleep_forever();
|
||||||
}
|
}
|
||||||
/* start thread with its initial IP and aligned SP */
|
/* start thread with its initial IP and aligned SP */
|
||||||
@ -105,4 +102,3 @@ void Thread_base::cancel_blocking()
|
|||||||
{
|
{
|
||||||
env()->cpu_session()->cancel_blocking(_thread_cap);
|
env()->cpu_session()->cancel_blocking(_thread_cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,6 @@
|
|||||||
|
|
||||||
/* main-thread UTCB-pointer for the Genode thread-API */
|
/* main-thread UTCB-pointer for the Genode thread-API */
|
||||||
.align 3
|
.align 3
|
||||||
.global _main_utcb
|
.global _main_thread_utcb
|
||||||
_main_utcb: .long 0
|
_main_thread_utcb: .long 0
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ namespace Genode {
|
|||||||
|
|
||||||
size_t stack_size() const { return _stack_size; }
|
size_t stack_size() const { return _stack_size; }
|
||||||
|
|
||||||
Native_utcb * utcb_phys() const { return _utcb_phys; }
|
Native_utcb * utcb_virt() const { return _utcb_virt; }
|
||||||
|
|
||||||
Ram_dataspace_capability utcb() const { return _utcb; }
|
Ram_dataspace_capability utcb() const { return _utcb; }
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
/* get core configuration */
|
/* get core configuration */
|
||||||
extern Genode::Native_utcb * _main_utcb;
|
extern Genode::Native_utcb * _main_thread_utcb;
|
||||||
extern int _kernel_stack_high;
|
extern int _kernel_stack_high;
|
||||||
extern "C" void CORE_MAIN();
|
extern "C" void CORE_MAIN();
|
||||||
|
|
||||||
@ -232,8 +232,9 @@ extern "C" void kernel()
|
|||||||
|
|
||||||
/* start thread with stack pointer at the top of stack */
|
/* start thread with stack pointer at the top of stack */
|
||||||
static Native_utcb utcb;
|
static Native_utcb utcb;
|
||||||
_main_utcb = &utcb;
|
|
||||||
static Thread t(Priority::MAX, "core");
|
static Thread t(Priority::MAX, "core");
|
||||||
|
_main_thread_utcb = &utcb;
|
||||||
|
_main_thread_utcb->startup_msg.init(t.id());
|
||||||
t.ip = (addr_t)CORE_MAIN;;
|
t.ip = (addr_t)CORE_MAIN;;
|
||||||
t.sp = (addr_t)s + STACK_SIZE;
|
t.sp = (addr_t)s + STACK_SIZE;
|
||||||
t.init(0, core_id(), &utcb, 1);
|
t.init(0, core_id(), &utcb, 1);
|
||||||
|
@ -449,9 +449,6 @@ void Thread::_call_yield_thread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Thread::_call_current_thread_id() { user_arg_0((Call_ret)id()); }
|
|
||||||
|
|
||||||
|
|
||||||
void Thread::_call_wait_for_request()
|
void Thread::_call_wait_for_request()
|
||||||
{
|
{
|
||||||
void * buf_base;
|
void * buf_base;
|
||||||
@ -870,7 +867,6 @@ void Thread::_call()
|
|||||||
case Call_id::START_THREAD: _call_start_thread(); return;
|
case Call_id::START_THREAD: _call_start_thread(); return;
|
||||||
case Call_id::PAUSE_THREAD: _call_pause_thread(); return;
|
case Call_id::PAUSE_THREAD: _call_pause_thread(); return;
|
||||||
case Call_id::RESUME_THREAD: _call_resume_thread(); return;
|
case Call_id::RESUME_THREAD: _call_resume_thread(); return;
|
||||||
case Call_id::CURRENT_THREAD_ID: _call_current_thread_id(); return;
|
|
||||||
case Call_id::YIELD_THREAD: _call_yield_thread(); return;
|
case Call_id::YIELD_THREAD: _call_yield_thread(); return;
|
||||||
case Call_id::REQUEST_AND_WAIT: _call_request_and_wait(); return;
|
case Call_id::REQUEST_AND_WAIT: _call_request_and_wait(); return;
|
||||||
case Call_id::REPLY: _call_reply(); return;
|
case Call_id::REPLY: _call_reply(); return;
|
||||||
|
@ -190,7 +190,6 @@ class Kernel::Thread
|
|||||||
void _call_pause_thread();
|
void _call_pause_thread();
|
||||||
void _call_resume_thread();
|
void _call_resume_thread();
|
||||||
void _call_yield_thread();
|
void _call_yield_thread();
|
||||||
void _call_current_thread_id();
|
|
||||||
void _call_wait_for_request();
|
void _call_wait_for_request();
|
||||||
void _call_request_and_wait();
|
void _call_request_and_wait();
|
||||||
void _call_reply();
|
void _call_reply();
|
||||||
|
@ -198,8 +198,9 @@ int Platform_thread::start(void * const ip, void * const sp,
|
|||||||
PERR("failed to initialize thread registers");
|
PERR("failed to initialize thread registers");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* let thread participate in CPU scheduling */
|
/* start executing new thread */
|
||||||
_tlb = Kernel::start_thread(id(), cpu_id, _pd_id, _utcb_phys);
|
_utcb_phys->startup_msg.init(_id);
|
||||||
|
_tlb = Kernel::start_thread(_id, cpu_id, _pd_id, _utcb_phys);
|
||||||
if (!_tlb) {
|
if (!_tlb) {
|
||||||
PERR("failed to start thread");
|
PERR("failed to start thread");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -22,18 +22,16 @@
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
extern Genode::Native_utcb * _main_utcb;
|
extern Genode::Native_utcb * _main_thread_utcb;
|
||||||
|
|
||||||
namespace Kernel { unsigned core_id(); }
|
namespace Kernel { unsigned core_id(); }
|
||||||
|
|
||||||
|
|
||||||
Native_utcb * Thread_base::utcb()
|
Native_utcb * Thread_base::utcb()
|
||||||
{
|
{
|
||||||
/* this is the main thread */
|
if (this) { return _tid.platform_thread->utcb_virt(); }
|
||||||
if (!this) { return _main_utcb; }
|
return _main_thread_utcb;
|
||||||
|
|
||||||
/* this isn't the main thread */
|
|
||||||
return _tid.pt->utcb_phys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -57,9 +55,10 @@ void Thread_base::_thread_start()
|
|||||||
|
|
||||||
|
|
||||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||||
: _list_element(this)
|
:
|
||||||
|
_list_element(this)
|
||||||
{
|
{
|
||||||
_tid.pt = new (platform()->core_mem_alloc())
|
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||||
Platform_thread(name, stack_size, Kernel::core_id());
|
Platform_thread(name, stack_size, Kernel::core_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ Thread_base::~Thread_base()
|
|||||||
void Thread_base::start()
|
void Thread_base::start()
|
||||||
{
|
{
|
||||||
/* allocate stack memory that fullfills the constraints for core stacks */
|
/* allocate stack memory that fullfills the constraints for core stacks */
|
||||||
size_t const size = _tid.pt->stack_size();
|
size_t const size = _tid.platform_thread->stack_size();
|
||||||
if (size > (1 << CORE_STACK_ALIGNM_LOG2) - sizeof(Core_thread_id)) {
|
if (size > (1 << CORE_STACK_ALIGNM_LOG2) - sizeof(Core_thread_id)) {
|
||||||
PERR("stack size does not fit stack alignment of core");
|
PERR("stack size does not fit stack alignment of core");
|
||||||
return;
|
return;
|
||||||
@ -92,7 +91,7 @@ void Thread_base::start()
|
|||||||
/* start thread with stack pointer at the top of stack */
|
/* start thread with stack pointer at the top of stack */
|
||||||
void * sp = (void *)((addr_t)base + size);
|
void * sp = (void *)((addr_t)base + size);
|
||||||
void * ip = (void *)&_thread_start;
|
void * ip = (void *)&_thread_start;
|
||||||
if (_tid.pt->start(ip, sp)) {
|
if (_tid.platform_thread->start(ip, sp)) {
|
||||||
PERR("failed to start thread");
|
PERR("failed to start thread");
|
||||||
alloc->free(base, size);
|
alloc->free(base, size);
|
||||||
return;
|
return;
|
||||||
@ -106,5 +105,8 @@ void Thread_base::join()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Thread_base::cancel_blocking() { _tid.pt->cancel_blocking(); }
|
void Thread_base::cancel_blocking()
|
||||||
|
{
|
||||||
|
_tid.platform_thread->cancel_blocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -14,18 +14,24 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/native_types.h>
|
#include <base/native_types.h>
|
||||||
|
#include <base/thread.h>
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
namespace Genode { void platform_main_bootstrap(); }
|
namespace Genode { void platform_main_bootstrap(); }
|
||||||
|
|
||||||
|
Native_thread_id _main_thread_id;
|
||||||
|
|
||||||
Genode::Native_thread_id main_thread_tid;
|
|
||||||
|
Native_thread_id Genode::thread_get_my_native_id()
|
||||||
|
{
|
||||||
|
Thread_base * const t = Thread_base::myself();
|
||||||
|
return t ? t->tid().thread_id : _main_thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Genode::platform_main_bootstrap()
|
void Genode::platform_main_bootstrap()
|
||||||
{
|
{
|
||||||
static struct Bootstrap
|
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||||
{
|
_main_thread_id = utcb->startup_msg.thread_id();
|
||||||
Bootstrap() { main_thread_tid = Kernel::current_thread_id(); }
|
|
||||||
} bootstrap;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user