mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +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
|
||||
{
|
||||
Native_thread_id tid;
|
||||
Platform_thread *pt;
|
||||
Platform_thread * platform_thread;
|
||||
Native_thread_id thread_id;
|
||||
};
|
||||
|
||||
typedef int Native_connection_state;
|
||||
@ -38,13 +38,12 @@ namespace Genode
|
||||
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()
|
||||
{ return Kernel::current_thread_id(); }
|
||||
Native_thread_id thread_get_my_native_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; }
|
||||
|
||||
@ -59,8 +58,9 @@ namespace Genode
|
||||
struct Type
|
||||
{
|
||||
enum Id {
|
||||
INVALID = 0,
|
||||
IPC = 1,
|
||||
INVALID = 0,
|
||||
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
|
||||
{
|
||||
union {
|
||||
uint8_t data[1 << MIN_MAPPING_SIZE_LOG2];
|
||||
Msg msg;
|
||||
Ipc_msg ipc_msg;
|
||||
};
|
||||
class 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; }
|
||||
};
|
||||
/**
|
||||
* Memory region that is exclusive to every thread and known by the kernel
|
||||
*/
|
||||
struct Native_utcb;
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
@ -145,7 +111,7 @@ namespace Genode
|
||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||
|
||||
/**
|
||||
* A coherent address region
|
||||
* Coherent address region
|
||||
*/
|
||||
struct Native_region
|
||||
{
|
||||
@ -170,5 +136,76 @@ namespace Genode
|
||||
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_ */
|
||||
|
||||
|
@ -43,29 +43,28 @@ namespace Kernel
|
||||
START_THREAD = 2,
|
||||
PAUSE_THREAD = 3,
|
||||
RESUME_THREAD = 4,
|
||||
CURRENT_THREAD_ID = 5,
|
||||
YIELD_THREAD = 6,
|
||||
ACCESS_THREAD_REGS = 7,
|
||||
ROUTE_THREAD_EVENT = 8,
|
||||
UPDATE_PD = 9,
|
||||
UPDATE_REGION = 10,
|
||||
NEW_PD = 11,
|
||||
KILL_PD = 12,
|
||||
REQUEST_AND_WAIT = 13,
|
||||
REPLY = 14,
|
||||
WAIT_FOR_REQUEST = 15,
|
||||
NEW_SIGNAL_RECEIVER = 16,
|
||||
NEW_SIGNAL_CONTEXT = 17,
|
||||
KILL_SIGNAL_CONTEXT = 18,
|
||||
KILL_SIGNAL_RECEIVER = 19,
|
||||
SUBMIT_SIGNAL = 20,
|
||||
AWAIT_SIGNAL = 21,
|
||||
SIGNAL_PENDING = 22,
|
||||
ACK_SIGNAL = 23,
|
||||
NEW_VM = 24,
|
||||
RUN_VM = 25,
|
||||
PAUSE_VM = 26,
|
||||
PRINT_CHAR = 27,
|
||||
YIELD_THREAD = 5,
|
||||
ACCESS_THREAD_REGS = 6,
|
||||
ROUTE_THREAD_EVENT = 7,
|
||||
UPDATE_PD = 8,
|
||||
UPDATE_REGION = 9,
|
||||
NEW_PD = 10,
|
||||
KILL_PD = 11,
|
||||
REQUEST_AND_WAIT = 12,
|
||||
REPLY = 13,
|
||||
WAIT_FOR_REQUEST = 14,
|
||||
NEW_SIGNAL_RECEIVER = 15,
|
||||
NEW_SIGNAL_CONTEXT = 16,
|
||||
KILL_SIGNAL_CONTEXT = 17,
|
||||
KILL_SIGNAL_RECEIVER = 18,
|
||||
SUBMIT_SIGNAL = 19,
|
||||
AWAIT_SIGNAL = 20,
|
||||
SIGNAL_PENDING = 21,
|
||||
ACK_SIGNAL = 22,
|
||||
NEW_VM = 23,
|
||||
RUN_VM = 24,
|
||||
PAUSE_VM = 25,
|
||||
PRINT_CHAR = 26,
|
||||
};
|
||||
};
|
||||
|
||||
@ -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
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* \brief Helper functions for the Lock implementation
|
||||
* \brief Helper functions for the lock implementation
|
||||
* \author Martin Stein
|
||||
* \date 2011-01-02
|
||||
*/
|
||||
@ -11,55 +11,56 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
#define _SRC__BASE__LOCK__LOCK_HELPER_H_
|
||||
#ifndef _LOCK_HELPER_H_
|
||||
#define _LOCK_HELPER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
extern Genode::Native_thread_id main_thread_tid;
|
||||
extern Genode::Native_thread_id _main_thread_id;
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to any other thread
|
||||
* Yield execution time-slice of current thread
|
||||
*/
|
||||
static inline void thread_yield()
|
||||
{ Kernel::yield_thread(); }
|
||||
static inline void thread_yield() { Kernel::yield_thread(); }
|
||||
|
||||
|
||||
/**
|
||||
* Yield CPU to a specified thread 't'
|
||||
* Return kernel name of thread t
|
||||
*/
|
||||
static inline void
|
||||
thread_switch_to(Genode::Thread_base *thread_base)
|
||||
static inline Genode::Native_thread_id
|
||||
native_thread_id(Genode::Thread_base * const t)
|
||||
{
|
||||
Genode::Native_thread_id t = thread_base ?
|
||||
thread_base->tid().tid :
|
||||
main_thread_tid;
|
||||
Kernel::yield_thread(t);
|
||||
return t ? t->tid().thread_id : _main_thread_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
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 ?
|
||||
thread_base->tid().tid :
|
||||
main_thread_tid;
|
||||
return Kernel::resume_thread(t) == 0;
|
||||
return Kernel::resume_thread(native_thread_id(t)) == 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exclude ourselves from CPU scheduling for now
|
||||
* Pause execution of current 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()
|
||||
{
|
||||
_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;
|
||||
|
||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is a main thread, so CRT0 provides UTCB through '_main_utcb' */
|
||||
if (!this) return __initial_sp;
|
||||
|
||||
/* otherwise we have a valid thread base */
|
||||
return &_context->utcb;
|
||||
if (this) { return &_context->utcb; }
|
||||
return __initial_sp;
|
||||
}
|
||||
|
||||
|
||||
@ -47,19 +47,16 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* detach UTCB */
|
||||
/* detach userland thread-context */
|
||||
size_t const size = sizeof(_context->utcb);
|
||||
addr_t utcb = Context_allocator::addr_to_base(_context) +
|
||||
Native_config::context_virtual_size() - size -
|
||||
Native_config::context_area_virtual_base();
|
||||
env_context_area_rm_session()->detach(utcb);
|
||||
|
||||
/* destroy object at the CPU session */
|
||||
/* destroy server object */
|
||||
env()->cpu_session()->kill_thread(_thread_cap);
|
||||
if (_pager_cap.valid()) {
|
||||
env()->rm_session()->remove_client(_pager_cap);
|
||||
@ -69,7 +66,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create thread at core */
|
||||
/* create server object */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
Cpu_session * cpu = env()->cpu_session();
|
||||
@ -78,11 +75,11 @@ void Thread_base::start()
|
||||
/* assign thread to protection domain */
|
||||
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);
|
||||
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
|
||||
|
||||
/* attach UTCB */
|
||||
/* attach userland thread-context */
|
||||
try {
|
||||
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
|
||||
size_t const size = sizeof(_context->utcb);
|
||||
@ -91,7 +88,7 @@ void Thread_base::start()
|
||||
Native_config::context_area_virtual_base();
|
||||
env_context_area_rm_session()->attach_at(ds, dst, size);
|
||||
} catch (...) {
|
||||
PERR("%s: Failed to attach UTCB", __PRETTY_FUNCTION__);
|
||||
PERR("failed to attach userland thread-context");
|
||||
sleep_forever();
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,6 @@
|
||||
|
||||
/* main-thread UTCB-pointer for the Genode thread-API */
|
||||
.align 3
|
||||
.global _main_utcb
|
||||
_main_utcb: .long 0
|
||||
.global _main_thread_utcb
|
||||
_main_thread_utcb: .long 0
|
||||
|
||||
|
@ -182,7 +182,7 @@ namespace Genode {
|
||||
|
||||
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; }
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
using namespace Kernel;
|
||||
|
||||
/* get core configuration */
|
||||
extern Genode::Native_utcb * _main_utcb;
|
||||
extern Genode::Native_utcb * _main_thread_utcb;
|
||||
extern int _kernel_stack_high;
|
||||
extern "C" void CORE_MAIN();
|
||||
|
||||
@ -232,8 +232,9 @@ extern "C" void kernel()
|
||||
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
static Native_utcb utcb;
|
||||
_main_utcb = &utcb;
|
||||
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.sp = (addr_t)s + STACK_SIZE;
|
||||
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 * buf_base;
|
||||
@ -870,7 +867,6 @@ void Thread::_call()
|
||||
case Call_id::START_THREAD: _call_start_thread(); return;
|
||||
case Call_id::PAUSE_THREAD: _call_pause_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::REQUEST_AND_WAIT: _call_request_and_wait(); return;
|
||||
case Call_id::REPLY: _call_reply(); return;
|
||||
|
@ -190,7 +190,6 @@ class Kernel::Thread
|
||||
void _call_pause_thread();
|
||||
void _call_resume_thread();
|
||||
void _call_yield_thread();
|
||||
void _call_current_thread_id();
|
||||
void _call_wait_for_request();
|
||||
void _call_request_and_wait();
|
||||
void _call_reply();
|
||||
|
@ -190,7 +190,7 @@ int Platform_thread::start(void * const ip, void * const sp,
|
||||
addr_t * write_regs = (addr_t *)Thread_base::myself()->utcb()->base();
|
||||
write_regs[0] = Reg_id::IP;
|
||||
write_regs[1] = Reg_id::SP;
|
||||
addr_t write_values[] = {
|
||||
addr_t write_values[] = {
|
||||
(addr_t)ip,
|
||||
_main_thread ? (addr_t)_utcb_virt : (addr_t)sp
|
||||
};
|
||||
@ -198,8 +198,9 @@ int Platform_thread::start(void * const ip, void * const sp,
|
||||
PERR("failed to initialize thread registers");
|
||||
return -1;
|
||||
}
|
||||
/* let thread participate in CPU scheduling */
|
||||
_tlb = Kernel::start_thread(id(), cpu_id, _pd_id, _utcb_phys);
|
||||
/* start executing new thread */
|
||||
_utcb_phys->startup_msg.init(_id);
|
||||
_tlb = Kernel::start_thread(_id, cpu_id, _pd_id, _utcb_phys);
|
||||
if (!_tlb) {
|
||||
PERR("failed to start thread");
|
||||
return -1;
|
||||
|
@ -22,18 +22,16 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern Genode::Native_utcb * _main_utcb;
|
||||
extern Genode::Native_utcb * _main_thread_utcb;
|
||||
|
||||
namespace Kernel { unsigned core_id(); }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
/* this is the main thread */
|
||||
if (!this) { return _main_utcb; }
|
||||
|
||||
/* this isn't the main thread */
|
||||
return _tid.pt->utcb_phys();
|
||||
if (this) { return _tid.platform_thread->utcb_virt(); }
|
||||
return _main_thread_utcb;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -57,9 +55,10 @@ void Thread_base::_thread_start()
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -74,7 +73,7 @@ Thread_base::~Thread_base()
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* 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)) {
|
||||
PERR("stack size does not fit stack alignment of core");
|
||||
return;
|
||||
@ -92,7 +91,7 @@ void Thread_base::start()
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
void * sp = (void *)((addr_t)base + size);
|
||||
void * ip = (void *)&_thread_start;
|
||||
if (_tid.pt->start(ip, sp)) {
|
||||
if (_tid.platform_thread->start(ip, sp)) {
|
||||
PERR("failed to start thread");
|
||||
alloc->free(base, size);
|
||||
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 */
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
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()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap() { main_thread_tid = Kernel::current_thread_id(); }
|
||||
} bootstrap;
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_main_thread_id = utcb->startup_msg.thread_id();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user