base: remove 'Native_thread' from public API

Issue #1832
This commit is contained in:
Norman Feske 2016-03-11 17:32:43 +01:00 committed by Christian Helmuth
parent dc0ebba1ec
commit da5d182ad3
77 changed files with 659 additions and 333 deletions

View File

@ -38,20 +38,6 @@ namespace Genode {
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
};
struct Native_thread
{
Fiasco::l4_threadid_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to
* the physical thread object, which is going to be destroyed
* on destruction of the 'Thread'.
*/
Platform_thread *pt;
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
typedef Fiasco::l4_threadid_t Native_connection_state;
}

View File

@ -14,10 +14,13 @@
/* Genode includes */
#include <base/printf.h>
/* Core includes */
/* core includes */
#include <ipc_pager.h>
#include <pager.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
namespace Fiasco {
#include <l4/sys/ipc.h>
#include <l4/sys/syscalls.h>
@ -80,5 +83,5 @@ void Ipc_pager::acknowledge_wakeup()
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
{
return Untyped_capability(_tid.l4id, badge);
return Untyped_capability(native_thread().l4id, badge);
}

View File

@ -37,15 +37,15 @@ void Thread_base::_thread_start()
void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform()->core_mem_alloc())
native_thread().pt = new(platform()->core_mem_alloc())
Platform_thread(0, _stack->name().string());
platform_specific()->core_pd()->bind_thread(_tid.pt);
platform_specific()->core_pd()->bind_thread(native_thread().pt);
_tid.pt->pager(platform_specific()->core_pager());
_tid.l4id = _tid.pt->native_thread_id();
native_thread().pt->pager(platform_specific()->core_pager());
native_thread().l4id = native_thread().pt->native_thread_id();
_tid.pt->start((void *)_thread_start, stack_top());
native_thread().pt->start((void *)_thread_start, stack_top());
}
@ -60,5 +60,5 @@ void Thread_base::cancel_blocking()
void Thread_base::_deinit_platform_thread()
{
/* destruct platform thread */
destroy(platform()->core_mem_alloc(), _tid.pt);
destroy(platform()->core_mem_alloc(), native_thread().pt);
}

View File

@ -0,0 +1,41 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
/* Genode includes */
#include <base/stdint.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
Fiasco::l4_threadid_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to the physical
* thread object, which is going to be destroyed on destruction of the
* 'Thread'.
*/
Platform_thread *pt;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -75,20 +75,11 @@ namespace Fiasco {
static bool valid(l4_cap_idx_t idx) {
return !(idx & L4_INVALID_CAP_BIT) && idx != 0; }
};
}
namespace Genode {
struct Native_thread
{
Fiasco::l4_cap_idx_t kcap = 0;
Native_thread() { }
explicit Native_thread(Fiasco::l4_cap_idx_t kcap) : kcap(kcap) { }
};
typedef Fiasco::l4_cap_idx_t Native_task;

View File

@ -0,0 +1,39 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*
* On most platforms, the 'Genode::Native_thread' type is private to the base
* framework. However, on Fiasco.OC, we make the type publicly available to
* expose the low-level thread-specific capability selectors to L4Linux.
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__FOC__NATIVE_THREAD_H_
#define _INCLUDE__FOC__NATIVE_THREAD_H_
/* Genode includes */
#include <base/stdint.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/types.h>
}
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
Fiasco::l4_cap_idx_t kcap = 0;
Native_thread() { }
explicit Native_thread(Fiasco::l4_cap_idx_t kcap) : kcap(kcap) { }
};
#endif /* _INCLUDE__FOC__NATIVE_THREAD_H_ */

View File

@ -27,6 +27,9 @@
#include <base/thread.h>
#include <signal_source/foc_signal_source.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
namespace Fiasco {
#include <l4/sys/irq.h>
}
@ -53,7 +56,7 @@ namespace Genode {
_sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
Thread_base::myself()->tid().kcap);
Thread_base::myself()->native_thread().kcap);
if (l4_error(tag))
PERR("l4_irq_attach failed with %ld!", l4_error(tag));
}

View File

@ -33,7 +33,7 @@ void Thread_base::_deinit_platform_thread()
{
using namespace Fiasco;
if (_tid.kcap && _thread_cap.valid()) {
if (native_thread().kcap && _thread_cap.valid()) {
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(utcb()->foc_utcb)->user[UTCB_TCR_BADGE];
cap_map()->remove(i);
_cpu_session->kill_thread(_thread_cap);
@ -62,7 +62,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
return;
}
/* adjust values whose computation differs for a main thread */
_tid.kcap = Fiasco::MAIN_THREAD_CAP;
native_thread().kcap = Fiasco::MAIN_THREAD_CAP;
_thread_cap = env()->parent()->main_thread_cap();
if (!_thread_cap.valid())
@ -91,7 +91,7 @@ void Thread_base::start()
Fiasco::l4_utcb_t * const foc_utcb = (Fiasco::l4_utcb_t *)state.utcb;
utcb()->foc_utcb = foc_utcb;
_tid = Native_thread(state.kcap);
native_thread() = Native_thread(state.kcap);
Cap_index *i = cap_map()->insert(state.id, state.kcap);
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;

View File

@ -17,6 +17,9 @@
/* Genode includes */
#include <base/cap_map.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
namespace Genode {
class Platform_thread;

View File

@ -23,6 +23,9 @@
#include <base/thread_state.h>
#include <util/touch.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/types.h>

View File

@ -18,9 +18,12 @@
#include <base/printf.h>
#include <base/lock.h>
/* Core includes */
/* core includes */
#include <pager.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/factory.h>

View File

@ -53,7 +53,7 @@ void Thread_base::start()
l4_utcb_t *foc_utcb = (l4_utcb_t *)(pt->utcb());
_tid = Native_thread(pt->gate().remote);
native_thread() = Native_thread(pt->gate().remote);
utcb()->foc_utcb = foc_utcb;

View File

@ -22,6 +22,9 @@
#include <base/native_types.h>
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Fiasco.OC includes */
namespace Fiasco {
#include <l4/sys/kdebug.h>
@ -48,7 +51,7 @@ static inline void thread_yield() { Fiasco::l4_thread_yield(); }
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
Fiasco::l4_cap_idx_t tid = thread_base ?
thread_base->tid().kcap :
thread_base->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_cap_idx_t irq = tid + Fiasco::THREAD_IRQ_CAP;
Fiasco::l4_irq_trigger(irq);
@ -62,7 +65,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
Fiasco::l4_cap_idx_t tid = thread_base ?
thread_base->tid().kcap :
thread_base->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_thread_switch(tid);
}
@ -82,7 +85,7 @@ static void thread_stop_myself()
Genode::Thread_base *myself = Genode::Thread_base::myself();
Fiasco::l4_cap_idx_t tid = myself ?
myself->tid().kcap :
myself->native_thread().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_cap_idx_t irq = tid + THREAD_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_NEVER);

View File

@ -0,0 +1,14 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#include <foc/native_thread.h>

View File

@ -15,32 +15,11 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
/* Genode includes */
#include <kernel/log.h>
#include <base/native_capability.h>
#include <base/ipc_msgbuf.h>
#include <base/printf.h>
namespace Genode
{
class Platform_thread;
class Native_thread;
typedef int Native_connection_state;
/**
* Coherent address region
*/
struct Native_region;
}
struct Genode::Native_thread
{
Platform_thread * platform_thread;
Native_capability cap;
};
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */

View File

@ -22,6 +22,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
#include <base/internal/native_thread.h>
/* base-hw includes */
#include <kernel/interface.h>
@ -85,7 +86,7 @@ void Ipc_istream::_wait()
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
:
Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()),
Native_capability(Thread_base::myself() ? Thread_base::myself()->tid().cap
Native_capability(Thread_base::myself() ? Thread_base::myself()->native_thread().cap
: Hw::_main_thread_cap),
_rcv_msg(rcv_msg), _rcv_cs(-1)
{ _read_offset = align_natural<unsigned>(RPC_OBJECT_ID_SIZE); }

View File

@ -77,4 +77,4 @@ void Thread_base::_thread_start()
}
void Thread_base::_thread_bootstrap() {
_tid.cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); }
native_thread().cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); }

View File

@ -62,7 +62,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
while (1) ;
}
/* adjust initial object state in case of a main thread */
tid().cap = Hw::_main_thread_cap;
native_thread().cap = Hw::_main_thread_cap;
_thread_cap = env()->parent()->main_thread_cap();
}

View File

@ -37,28 +37,28 @@ namespace Hw { extern Untyped_capability _main_thread_cap; }
void Thread_base::start()
{
/* start thread with stack pointer at the top of stack */
if (_tid.platform_thread->start((void *)&_thread_start, stack_top()))
if (native_thread().platform_thread->start((void *)&_thread_start, stack_top()))
PERR("failed to start thread");
}
void Thread_base::cancel_blocking()
{
_tid.platform_thread->cancel_blocking();
native_thread().platform_thread->cancel_blocking();
}
void Thread_base::_deinit_platform_thread()
{
/* destruct platform thread */
destroy(platform()->core_mem_alloc(), _tid.platform_thread);
destroy(platform()->core_mem_alloc(), native_thread().platform_thread);
}
void Thread_base::_init_platform_thread(size_t, Type type)
{
if (type == NORMAL) {
_tid.platform_thread = new (platform()->core_mem_alloc())
native_thread().platform_thread = new (platform()->core_mem_alloc())
Platform_thread(_stack->name().string(), &_stack->utcb());
return;
}
@ -69,5 +69,5 @@ void Thread_base::_init_platform_thread(size_t, Type type)
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
/* adjust initial object state in case of a main thread */
tid().cap = Hw::_main_thread_cap.dst();
native_thread().cap = Hw::_main_thread_cap.dst();
}

View File

@ -35,7 +35,7 @@ static inline void thread_yield() {
static inline Kernel::capid_t
native_thread_id(Genode::Thread_base * const t)
{
return t ? t->tid().cap.dst() : Hw::_main_thread_cap.dst();
return t ? t->native_thread().cap.dst() : Hw::_main_thread_cap.dst();
}

View File

@ -0,0 +1,33 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#include <base/stdint.h>
#include <base/native_capability.h>
namespace Genode {
struct Native_thread;
class Platform_thread;
}
struct Genode::Native_thread
{
Platform_thread *platform_thread;
Native_capability cap;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -20,39 +20,6 @@
namespace Genode {
/**
* Native thread contains more thread-local data than just the ID
*/
struct Native_thread
{
/*
* Unfortunately, both - PID and TID - are needed for lx_tgkill()
*/
unsigned int tid = 0; /* Native thread ID type as returned by the
'clone' system call */
unsigned int pid = 0; /* process ID (resp. thread-group ID) */
bool is_ipc_server = false;
/**
* Natively aligned memory location used in the lock implementation
*/
int futex_counter __attribute__((aligned(sizeof(Genode::addr_t)))) = 0;
struct Meta_data;
/**
* Opaque pointer to additional thread-specific meta data
*
* This pointer is used by hybrid Linux/Genode programs to maintain
* POSIX-thread-related meta data. For non-hybrid Genode programs, it
* remains unused.
*/
Meta_data *meta_data = nullptr;
Native_thread() { }
};
struct Cap_dst_policy
{
struct Dst

View File

@ -36,6 +36,7 @@
/* base-internal includes */
#include <base/internal/socket_descriptor_registry.h>
#include <base/internal/native_thread.h>
/* Linux includes */
#include <linux_syscalls.h>
@ -509,7 +510,7 @@ Ipc_istream::~Ipc_istream()
*/
Thread_base *thread = Thread_base::myself();
if (thread)
thread->tid().is_ipc_server = false;
thread->native_thread().is_ipc_server = false;
}
destroy_server_socket_pair(_rcv_cs);
@ -641,7 +642,7 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
* may call 'sleep_forever()', which instantiates 'Ipc_server'.
*/
if (thread && thread->tid().is_ipc_server) {
if (thread && thread->native_thread().is_ipc_server) {
PRAW("[%d] unexpected multiple instantiation of Ipc_server by one thread",
lx_gettid());
struct Ipc_server_multiple_instance { };
@ -650,7 +651,7 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
if (thread) {
_rcv_cs = server_socket_pair();
thread->tid().is_ipc_server = true;
thread->native_thread().is_ipc_server = true;
}
/* override capability initialization performed by 'Ipc_istream' */

View File

@ -58,7 +58,7 @@ void Thread_base::_thread_start()
/* inform core about the new thread and process ID of the new thread */
Linux_cpu_session *cpu = dynamic_cast<Linux_cpu_session *>(thread->_cpu_session);
if (cpu)
cpu->thread_id(thread->cap(), thread->tid().pid, thread->tid().tid);
cpu->thread_id(thread->cap(), thread->native_thread().pid, thread->native_thread().tid);
/* wakeup 'start' function */
startup_lock().unlock();
@ -84,7 +84,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
return;
}
/* adjust initial object state for main threads */
tid().futex_counter = main_thread_futex_counter;
native_thread().futex_counter = main_thread_futex_counter;
_thread_cap = env()->parent()->main_thread_cap();
}
@ -106,7 +106,7 @@ void Thread_base::_deinit_platform_thread()
for (;;) {
/* destroy thread locally */
int ret = lx_tgkill(_tid.pid, _tid.tid, LX_SIGCANCEL);
int ret = lx_tgkill(native_thread().pid, native_thread().tid, LX_SIGCANCEL);
if (ret < 0) break;
@ -138,8 +138,8 @@ void Thread_base::start()
threadlib_initialized = true;
}
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
_tid.pid = lx_getpid();
native_thread().tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
native_thread().pid = lx_getpid();
/* wait until the 'thread_start' function got entered */
startup_lock().lock();

View File

@ -15,6 +15,9 @@
#include <base/lock.h>
#include <linux_dataspace/client.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* local includes */
#include "platform.h"
#include "core_env.h"
@ -157,7 +160,7 @@ namespace Genode {
Native_connection_state server_socket_pair()
{
return create_server_socket_pair(Thread_base::myself()->tid().tid);
return create_server_socket_pair(Thread_base::myself()->native_thread().tid);
}
void destroy_server_socket_pair(Native_connection_state const &ncs)

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Linux syscall bindings */
#include <linux_syscalls.h>
@ -54,8 +57,8 @@ void Thread_base::_deinit_platform_thread() { }
void Thread_base::start()
{
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
_tid.pid = lx_getpid();
native_thread().tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
native_thread().pid = lx_getpid();
}

View File

@ -41,7 +41,7 @@ static inline void thread_yield()
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
const int *futex_counter_ptr = thread_base ?
&thread_base->tid().futex_counter :
&thread_base->native_thread().futex_counter :
&main_thread_futex_counter;
return lx_futex(futex_counter_ptr, LX_FUTEX_WAKE, 1);
}
@ -62,7 +62,7 @@ static inline void thread_stop_myself()
*/
Genode::Thread_base *myself = Genode::Thread_base::myself();
const int *futex_counter_ptr = myself ?
&myself->tid().futex_counter :
&myself->native_thread().futex_counter :
&main_thread_futex_counter;
lx_futex(futex_counter_ptr, LX_FUTEX_WAIT, 0);
}

View File

@ -0,0 +1,51 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#include <base/stdint.h>
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
/*
* Unfortunately, both - PID and TID - are needed for lx_tgkill()
*/
unsigned int tid = 0; /* Native thread ID type as returned by the
'clone' system call */
unsigned int pid = 0; /* process ID (resp. thread-group ID) */
bool is_ipc_server = false;
/**
* Natively aligned memory location used in the lock implementation
*/
int futex_counter __attribute__((aligned(sizeof(Genode::addr_t)))) = 0;
struct Meta_data;
/**
* Opaque pointer to additional thread-specific meta data
*
* This pointer is used by hybrid Linux/Genode programs to maintain
* POSIX-thread-related meta data. For non-hybrid Genode programs, it
* remains unused.
*/
Meta_data *meta_data = nullptr;
Native_thread() { }
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -11,11 +11,14 @@
* under the terms of the GNU General Public License version 2.
*/
//#include <base/crt0.h>
/* Genode includes */
#include <base/printf.h>
#include <linux_syscalls.h>
#include <linux_cpu_session/linux_cpu_session.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
extern "C" int raw_write_str(const char *str);
@ -134,8 +137,20 @@ static pthread_key_t tls_key()
namespace Genode {
/**
* Meta data tied to the thread via the pthread TLS mechanism
*/
struct Native_thread::Meta_data
{
/**
* Linux-specific thread meta data
*
* For non-hybrid programs, this information is located at the
* 'Stack'. But the POSIX threads of hybrid programs have no 'Stack'
* object. So we have to keep the meta data here.
*/
Native_thread native_thread;
/**
* Filled out by 'thread_start' function in the stack of the new
* thread
@ -152,7 +167,10 @@ namespace Genode {
*
* \param thread associated 'Thread_base' object
*/
Meta_data(Thread_base *thread) : thread_base(thread) { }
Meta_data(Thread_base *thread) : thread_base(thread)
{
native_thread.meta_data = this;
}
/**
* Used to block the constructor until the new thread has initialized
@ -174,8 +192,8 @@ namespace Genode {
virtual void joined() = 0;
};
/*
* Thread meta data for a thread created by Genode
/**
* Thread meta data for a thread created by Genode
*/
class Thread_meta_data_created : public Native_thread::Meta_data
{
@ -238,8 +256,8 @@ namespace Genode {
}
};
/*
* Thread meta data for an adopted thread
/**
* Thread meta data for an adopted thread
*/
class Thread_meta_data_adopted : public Native_thread::Meta_data
{
@ -320,7 +338,7 @@ static void adopt_thread(Native_thread::Meta_data *meta_data)
/*
* Initialize thread meta data
*/
Native_thread &native_thread = meta_data->thread_base->tid();
Native_thread &native_thread = meta_data->thread_base->native_thread();
native_thread.tid = lx_gettid();
native_thread.pid = lx_getpid();
}
@ -375,19 +393,18 @@ Thread_base *Thread_base::myself()
* thread, which is not what we want. For the allocation, we use glibc
* malloc because 'Genode::env()->heap()->alloc()' uses IPC.
*
* XXX Both the 'Thread_base' and 'Threadm_meta_data' objects are never
* freed.
* XXX Both the 'Thread_base' and 'Native_thread::Meta_data' objects are
* never freed.
*/
Thread_base *thread = (Thread_base *)malloc(sizeof(Thread_base));
memset(thread, 0, sizeof(*thread));
Native_thread::Meta_data *meta_data = new Thread_meta_data_adopted(thread);
/*
* Initialize 'Thread_base::_tid' using the default constructor of
* 'Native_thread'. This marks the client and server sockets as
* uninitialized and prompts the IPC framework to create those as needed.
* Initialize 'Thread_base::_native_thread' to point to the default-
* constructed 'Native_thread' (part of 'Meta_data').
*/
meta_data->thread_base->tid() = Native_thread();
meta_data->thread_base->_native_thread = &meta_data->native_thread;
adopt_thread(meta_data);
return thread;
@ -399,37 +416,42 @@ void Thread_base::start()
/*
* Unblock thread that is supposed to slumber in 'thread_start'.
*/
_tid.meta_data->started();
native_thread().meta_data->started();
}
void Thread_base::join()
{
_tid.meta_data->wait_for_join();
native_thread().meta_data->wait_for_join();
}
Native_thread &Thread_base::native_thread() { return *_native_thread; }
Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size,
Type type, Cpu_session * cpu_sess)
: _cpu_session(cpu_sess)
{
_tid.meta_data = new (env()->heap()) Thread_meta_data_created(this);
Native_thread::Meta_data *meta_data =
new (env()->heap()) Thread_meta_data_created(this);
int const ret = pthread_create(&_tid.meta_data->pt, 0, thread_start,
_tid.meta_data);
_native_thread = &meta_data->native_thread;
int const ret = pthread_create(&meta_data->pt, 0, thread_start, meta_data);
if (ret) {
PERR("pthread_create failed (returned %d, errno=%d)",
ret, errno);
destroy(env()->heap(), _tid.meta_data);
destroy(env()->heap(), meta_data);
throw Out_of_stack_space();
}
_tid.meta_data->wait_for_construction();
native_thread().meta_data->wait_for_construction();
Linux_cpu_session *cpu = cpu_session(_cpu_session);
_thread_cap = cpu->create_thread(weight, name);
cpu->thread_id(_thread_cap, _tid.pid, _tid.tid);
cpu->thread_id(_thread_cap, native_thread().pid, native_thread().tid);
}
@ -447,22 +469,22 @@ void Thread_base::cancel_blocking()
Thread_base::~Thread_base()
{
bool const needs_join = (pthread_cancel(_tid.meta_data->pt) == 0);
bool const needs_join = (pthread_cancel(native_thread().meta_data->pt) == 0);
if (needs_join) {
int const ret = pthread_join(_tid.meta_data->pt, 0);
int const ret = pthread_join(native_thread().meta_data->pt, 0);
if (ret)
PWRN("pthread_join unexpectedly returned with %d (errno=%d)",
ret, errno);
}
Thread_meta_data_created *meta_data =
dynamic_cast<Thread_meta_data_created *>(_tid.meta_data);
dynamic_cast<Thread_meta_data_created *>(native_thread().meta_data);
if (meta_data)
destroy(env()->heap(), meta_data);
_tid.meta_data = 0;
_native_thread = nullptr;
/* inform core about the killed thread */
cpu_session(_cpu_session)->kill_thread(_thread_cap);

View File

@ -15,27 +15,16 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
/* Genode includes */
#include <base/native_capability.h>
#include <base/stdint.h>
#include <nova/syscalls.h>
#include <base/cap_map.h>
/* NOVA includes */
#include <nova/syscalls.h>
namespace Genode {
struct Native_thread
{
enum { INVALID_INDEX = ~0UL };
addr_t ec_sel; /* NOVA cap selector for execution context */
addr_t exc_pt_sel; /* base of event portal window */
bool is_vcpu;
Native_thread() : ec_sel(INVALID_INDEX),
exc_pt_sel (INVALID_INDEX), is_vcpu(false) {}
};
class Native_capability
{
public:

View File

@ -0,0 +1,38 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*
* On most platforms, the 'Genode::Native_thread' type is private to the
* base framework. However, on NOVA, we make the type publicly available to
* expose the low-level thread-specific capability selectors to user-level
* virtual-machine monitors (Seoul or VirtualBox).
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__NOVA__NATIVE_THREAD_H_
#define _INCLUDE__NOVA__NATIVE_THREAD_H_
#include <base/stdint.h>
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
enum { INVALID_INDEX = ~0UL };
addr_t ec_sel; /* selector for execution context */
addr_t exc_pt_sel; /* base of event portal window */
bool is_vcpu;
Native_thread() : ec_sel(INVALID_INDEX),
exc_pt_sel(INVALID_INDEX), is_vcpu(false) { }
};
#endif /* _INCLUDE__NOVA__NATIVE_THREAD_H_ */

View File

@ -21,9 +21,13 @@
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
/* Genode includes */
#include <base/rpc_client.h>
#include <signal_source/nova_signal_source.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
@ -49,9 +53,9 @@ namespace Genode {
/* request mapping of semaphore capability selector */
Thread_base * myself = Thread_base::myself();
request_signal_sm_cap(Native_capability(myself->tid().ec_sel + 1),
myself->tid().exc_pt_sel + Nova::PT_SEL_STARTUP);
_sem = Native_capability(myself->tid().exc_pt_sel + Nova::PT_SEL_STARTUP);
request_signal_sm_cap(Native_capability(myself->native_thread().ec_sel + 1),
myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
_sem = Native_capability(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
call<Rpc_register_semaphore>(_sem);
}

View File

@ -39,8 +39,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
Untyped_capability ec_cap;
/* _ec_sel is invalid until thread gets started */
if (tid().ec_sel != Native_thread::INVALID_INDEX)
ec_cap = Native_capability(tid().ec_sel);
if (native_thread().ec_sel != Native_thread::INVALID_INDEX)
ec_cap = Native_capability(native_thread().ec_sel);
else
ec_cap = _thread_cap;
@ -193,14 +193,14 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
_pd_session(*pd_session)
{
/* when not running in core set the affinity via cpu session */
if (_tid.ec_sel == Native_thread::INVALID_INDEX) {
if (native_thread().ec_sel == Native_thread::INVALID_INDEX) {
/* place new thread on the specified CPU */
if (location.valid())
_cpu_session->affinity(_thread_cap, location);
/* magic value evaluated by thread_nova.cc to start a local thread */
_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
} else {
/* tell affinity CPU in 'core' via stack */
reinterpret_cast<Affinity::Location *>(stack_base())[0] = location;
@ -210,7 +210,7 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
Thread_base::start();
/* create cleanup portal */
_cap = _alloc_rpc_cap(_pd_session, Native_capability(_tid.ec_sel),
_cap = _alloc_rpc_cap(_pd_session, Native_capability(native_thread().ec_sel),
(addr_t)_activation_entry);
if (!_cap.valid())
throw Cpu_session::Thread_creation_failed();

View File

@ -16,6 +16,9 @@
#include <base/sleep.h>
#include <base/lock.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
@ -25,7 +28,7 @@ void Genode::sleep_forever()
using namespace Nova;
Thread_base *myself = Thread_base::myself();
addr_t sem = myself ? myself->tid().exc_pt_sel + SM_SEL_EC : SM_SEL_EC;
addr_t sem = myself ? myself->native_thread().exc_pt_sel + SM_SEL_EC : SM_SEL_EC;
while (1) {
if (Nova::sm_ctrl(sem, SEMAPHORE_DOWNZERO))

View File

@ -75,7 +75,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
* Allocate capability selectors for the thread's execution context,
* running semaphore and exception handler portals.
*/
_tid.ec_sel = Native_thread::INVALID_INDEX;
native_thread().ec_sel = Native_thread::INVALID_INDEX;
/* for main threads the member initialization differs */
if (type == MAIN || type == REINITIALIZED_MAIN) {
@ -84,10 +84,10 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER);
_pager_cap = reinterpret_cap_cast<Pager_object>(pager_cap);
_tid.exc_pt_sel = 0;
_tid.ec_sel = Nova::PT_SEL_MAIN_EC;
native_thread().exc_pt_sel = 0;
native_thread().ec_sel = Nova::PT_SEL_MAIN_EC;
request_native_ec_cap(_pager_cap, _tid.ec_sel);
request_native_ec_cap(_pager_cap, native_thread().ec_sel);
return;
}
@ -104,8 +104,8 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
revoke(Mem_crd(utcb >> 12, 0, rwx));
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
if (_tid.exc_pt_sel == Native_thread::INVALID_INDEX)
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
if (native_thread().exc_pt_sel == Native_thread::INVALID_INDEX)
throw Cpu_session::Thread_creation_failed();
/* if no cpu session is given, use it from the environment */
@ -131,16 +131,16 @@ void Thread_base::_deinit_platform_thread()
{
using namespace Nova;
if (_tid.ec_sel != Native_thread::INVALID_INDEX) {
revoke(Obj_crd(_tid.ec_sel, 1));
cap_map()->remove(_tid.ec_sel, 1, false);
if (native_thread().ec_sel != Native_thread::INVALID_INDEX) {
revoke(Obj_crd(native_thread().ec_sel, 1));
cap_map()->remove(native_thread().ec_sel, 1, false);
}
/* de-announce thread */
if (_thread_cap.valid())
_cpu_session->kill_thread(_thread_cap);
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2);
cap_map()->remove(native_thread().exc_pt_sel, NUM_INITIAL_PT_LOG2);
if (_pager_cap.valid())
env()->rm_session()->remove_client(_pager_cap);
@ -149,14 +149,14 @@ void Thread_base::_deinit_platform_thread()
void Thread_base::start()
{
if (_tid.ec_sel < Native_thread::INVALID_INDEX - 1)
if (native_thread().ec_sel < Native_thread::INVALID_INDEX - 1)
throw Cpu_session::Thread_creation_failed();
/*
* Default: create global thread - ec.sel == INVALID_INDEX
* create local thread - ec.sel == INVALID_INDEX - 1
*/
bool global = _tid.ec_sel == Native_thread::INVALID_INDEX;
bool global = native_thread().ec_sel == Native_thread::INVALID_INDEX;
using namespace Genode;
@ -170,8 +170,8 @@ void Thread_base::start()
/* create EC at core */
Thread_state state;
state.sel_exc_base = _tid.exc_pt_sel;
state.is_vcpu = _tid.is_vcpu;
state.sel_exc_base = native_thread().exc_pt_sel;
state.is_vcpu = native_thread().is_vcpu;
/* local thread have no start instruction pointer - set via portal entry */
addr_t thread_ip = global ? reinterpret_cast<addr_t>(_thread_start) : 0;
@ -183,19 +183,19 @@ void Thread_base::start()
throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */
_tid.ec_sel = cap_map()->insert(1);
if (_tid.ec_sel == Native_thread::INVALID_INDEX)
native_thread().ec_sel = cap_map()->insert(1);
if (native_thread().ec_sel == Native_thread::INVALID_INDEX)
throw Cpu_session::Thread_creation_failed();
/* requested pager cap used by request_native_ec_cap in Signal_source_client */
enum { MAP_PAGER_CAP = 1 };
request_native_ec_cap(_pager_cap, _tid.ec_sel, MAP_PAGER_CAP);
request_native_ec_cap(_pager_cap, native_thread().ec_sel, MAP_PAGER_CAP);
using namespace Nova;
/* request exception portals for normal threads */
if (!_tid.is_vcpu) {
request_event_portal(_pager_cap, _tid.exc_pt_sel, 0, NUM_INITIAL_PT_LOG2);
if (!native_thread().is_vcpu) {
request_event_portal(_pager_cap, native_thread().exc_pt_sel, 0, NUM_INITIAL_PT_LOG2);
/* default: we don't accept any mappings or translations */
Utcb * utcb_obj = reinterpret_cast<Utcb *>(utcb());
@ -213,6 +213,6 @@ void Thread_base::cancel_blocking()
{
using namespace Nova;
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
if (sm_ctrl(native_thread().exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
nova_die();
}

View File

@ -18,6 +18,9 @@
#include <util/construct_at.h>
#include <rm_session/rm_session.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* core-local includes */
#include <pager.h>
#include <imprint_badge.h>
@ -444,7 +447,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
throw Rm_session::Invalid_thread();
}
addr_t const ec_sel = pager_threads[use_cpu]->tid().ec_sel;
addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
/* compiler generates instance of exception entry if not specified */
addr_t entry = func ? (addr_t)func : (addr_t)(&_handler<EV>);
@ -531,7 +534,7 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
throw Rm_session::Invalid_thread();
}
addr_t ec_sel = pager_threads[use_cpu]->tid().ec_sel;
addr_t ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
/* create portal for page-fault handler - 14 */
_exceptions.register_handler<14>(this, Mtd::QUAL | Mtd::EIP,
@ -720,7 +723,7 @@ void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
if (assert) {
PERR("unknown OOM case - stop core pager thread");
utcb->set_msg_word(0);
reply(myself->stack_top(), myself->tid().exc_pt_sel + Nova::SM_SEL_EC);
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
}
/* be strict in case of the -strict- STOP policy - stop causing thread */
@ -740,7 +743,7 @@ void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
/* should not happen on Genode - we create and know every PD in core */
PERR("Unknown PD has insufficient kernel memory left - stop thread");
utcb->set_msg_word(0);
reply(myself->stack_top(), myself->tid().exc_pt_sel + Nova::SM_SEL_EC);
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
case SRC_CORE_PD:
/* core PD -> other PD, which has insufficient kernel resources */
@ -792,7 +795,7 @@ addr_t Pager_object::get_oom_portal()
unsigned const use_cpu = location.xpos();
if (kernel_hip()->is_cpu_enabled(use_cpu) && pager_threads[use_cpu]) {
addr_t const ec_sel = pager_threads[use_cpu]->tid().ec_sel;
addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
uint8_t res = create_portal(pt_oom, __core_pd_sel, ec_sel, Mtd(0),
reinterpret_cast<addr_t>(_oom_handler),
@ -866,7 +869,7 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
PWRN("invalid CPU parameter used in pager object");
return Pager_capability();
}
Native_capability pager_thread_cap(pager_threads[use_cpu]->tid().ec_sel);
Native_capability pager_thread_cap(pager_threads[use_cpu]->native_thread().ec_sel);
/* request creation of portal bind to pager thread */
Native_capability cap_session =

View File

@ -42,23 +42,23 @@ void Thread_base::_init_platform_thread(size_t, Type type)
if (type == MAIN)
{
/* set EC selector according to NOVA spec */
_tid.ec_sel = Platform_pd::pd_core_sel() + 1;
native_thread().ec_sel = Platform_pd::pd_core_sel() + 1;
/*
* Exception base of first thread in core is 0. We have to set
* it here so that Thread_base code finds the semaphore of the
* main thread.
*/
_tid.exc_pt_sel = 0;
native_thread().exc_pt_sel = 0;
return;
}
_tid.ec_sel = cap_map()->insert(1);
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
native_thread().ec_sel = cap_map()->insert(1);
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
addr_t pd_sel = Platform_pd::pd_core_sel();
/* create running semaphore required for locking */
addr_t rs_sel =_tid.exc_pt_sel + SM_SEL_EC;
addr_t rs_sel =native_thread().exc_pt_sel + SM_SEL_EC;
uint8_t res = create_sm(rs_sel, pd_sel, 0);
if (res != NOVA_OK) {
PERR("create_sm returned %u", res);
@ -69,11 +69,11 @@ void Thread_base::_init_platform_thread(size_t, Type type)
void Thread_base::_deinit_platform_thread()
{
unmap_local(Nova::Obj_crd(_tid.ec_sel, 1));
unmap_local(Nova::Obj_crd(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
unmap_local(Nova::Obj_crd(native_thread().ec_sel, 1));
unmap_local(Nova::Obj_crd(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
cap_map()->remove(_tid.ec_sel, 1, false);
cap_map()->remove(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2, false);
cap_map()->remove(native_thread().ec_sel, 1, false);
cap_map()->remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2, false);
/* revoke utcb */
Nova::Rights rwx(true, true, true);
@ -106,8 +106,8 @@ void Thread_base::start()
/* create local EC */
enum { LOCAL_THREAD = false };
uint8_t res = create_ec(_tid.ec_sel, pd_sel, location.xpos(),
utcb, sp, _tid.exc_pt_sel, LOCAL_THREAD);
uint8_t res = create_ec(native_thread().ec_sel, pd_sel, location.xpos(),
utcb, sp, native_thread().exc_pt_sel, LOCAL_THREAD);
if (res != NOVA_OK) {
PERR("create_ec returned %d cpu=%u", res, location.xpos());
throw Cpu_session::Thread_creation_failed();
@ -119,7 +119,7 @@ void Thread_base::start()
if (map_local(reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb()),
Obj_crd(PT_SEL_PAGE_FAULT, 0),
Obj_crd(_tid.exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
Obj_crd(native_thread().exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
PERR("could not create page fault portal");
throw Cpu_session::Thread_creation_failed();
}
@ -130,6 +130,6 @@ void Thread_base::cancel_blocking()
{
using namespace Nova;
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
if (sm_ctrl(native_thread().exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
nova_die();
}

View File

@ -23,6 +23,9 @@
#include <base/thread.h>
#include <base/stdint.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
@ -34,7 +37,7 @@ extern int main_thread_running_semaphore();
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
Genode::addr_t sem = thread_base ?
thread_base->tid().exc_pt_sel + Nova::SM_SEL_EC :
thread_base->native_thread().exc_pt_sel + Nova::SM_SEL_EC :
main_thread_running_semaphore();
Nova::sm_ctrl(sem, Nova::SEMAPHORE_UP);
@ -53,7 +56,7 @@ static inline void thread_stop_myself()
addr_t sem;
Thread_base *myself = Thread_base::myself();
if (myself)
sem = myself->tid().exc_pt_sel + SM_SEL_EC;
sem = myself->native_thread().exc_pt_sel + SM_SEL_EC;
else
sem = main_thread_running_semaphore();

View File

@ -0,0 +1,14 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#include <nova/native_thread.h>

View File

@ -35,7 +35,7 @@ static inline void spinlock_lock(volatile T *lock_variable)
using Genode::cmpxchg;
Genode::Thread_base * myself = Genode::Thread_base::myself();
T const tid = myself ? myself->tid().ec_sel : Nova::PT_SEL_MAIN_EC;
T const tid = myself ? myself->native_thread().ec_sel : Nova::PT_SEL_MAIN_EC;
unsigned help_counter = 0;

View File

@ -23,6 +23,7 @@
#include <os/config.h>
#include <trace/timestamp.h>
#include <nova/native_thread.h>
#include "server.h"
@ -199,7 +200,7 @@ class Greedy : public Thread<4096> {
Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb());
Nova::Rights const mapping_rwx(true, true, true);
addr_t const page_fault_portal = tid().exc_pt_sel + 14;
addr_t const page_fault_portal = native_thread().exc_pt_sel + 14;
PERR("cause mappings in range [0x%lx, 0x%lx) %p", mem,
mem + SUB_RM_SIZE - 1, &mem);
@ -268,7 +269,7 @@ int main(int argc, char **argv)
return -__LINE__;
addr_t sel_pd = cap_map()->insert();
addr_t sel_ec = myself->tid().ec_sel;
addr_t sel_ec = myself->native_thread().ec_sel;
addr_t sel_cap = cap_map()->insert();
addr_t handler = 0UL;
uint8_t res = 0;
@ -287,7 +288,7 @@ int main(int argc, char **argv)
/* changing the badge of one of the portal must fail */
for (unsigned i = 0; i < (1U << Nova::NUM_INITIAL_PT_LOG2); i++) {
addr_t sel_exc = myself->tid().exc_pt_sel + i;
addr_t sel_exc = myself->native_thread().exc_pt_sel + i;
res = Nova::pt_ctrl(sel_exc, 0xbadbad);
check(res, "pt_ctrl %2u", i);
}

View File

@ -23,27 +23,12 @@ namespace Okl4 { extern "C" {
namespace Genode {
class Platform_thread;
/**
* Index of the UTCB's thread word used for storing the own global
* thread ID
*/
enum { UTCB_TCR_THREAD_WORD_MYSELF = 0 };
struct Native_thread
{
Okl4::L4_ThreadId_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to
* the physical thread object, which is going to be destroyed
* on destruction of the 'Thread'.
*/
Platform_thread *pt;
};
struct Cap_dst_policy
{

View File

@ -16,14 +16,14 @@
#include <base/thread.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* OKL4 includes */
namespace Okl4
{
extern "C" {
#include <l4/utcb.h>
#include <l4/thread.h>
}
}
namespace Okl4 { extern "C" {
#include <l4/utcb.h>
#include <l4/thread.h>
} }
Okl4::L4_ThreadId_t main_thread_tid;
@ -75,13 +75,13 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
void Genode::Thread_base::_thread_bootstrap()
{
_tid.l4id.raw = Okl4::copy_uregister_to_utcb();
native_thread().l4id.raw = Okl4::copy_uregister_to_utcb();
}
void Genode::Thread_base::_init_platform_thread(size_t, Type type)
{
if (type == NORMAL) { return; }
_tid.l4id.raw = main_thread_tid.raw;
native_thread().l4id.raw = main_thread_tid.raw;
_thread_cap = env()->parent()->main_thread_cap();
}

View File

@ -19,6 +19,9 @@
#include <pager.h>
#include <platform_thread.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
namespace Okl4 { extern "C" {
#include <l4/message.h>
#include <l4/ipc.h>
@ -152,5 +155,5 @@ void Ipc_pager::acknowledge_wakeup()
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
{
return Untyped_capability(_tid.l4id, badge);
return Untyped_capability(native_thread().l4id, badge);
}

View File

@ -37,13 +37,13 @@ void Thread_base::_thread_start()
void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform_specific()->thread_slab())
native_thread().pt = new(platform_specific()->thread_slab())
Platform_thread(0, _stack->name().string());
if (platform_specific()->core_pd()->bind_thread(_tid.pt))
if (platform_specific()->core_pd()->bind_thread(native_thread().pt))
throw Cpu_session::Thread_creation_failed();
_tid.pt->start((void *)_thread_start, stack_top());
native_thread().pt->start((void *)_thread_start, stack_top());
}
@ -58,5 +58,5 @@ void Thread_base::cancel_blocking()
void Thread_base::_deinit_platform_thread()
{
/* destruct platform thread */
destroy(platform_specific()->thread_slab(), _tid.pt);
destroy(platform_specific()->thread_slab(), native_thread().pt);
}

View File

@ -55,7 +55,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
L4_ThreadState_t state;
Okl4::L4_ThreadId_t tid = thread_base ?
thread_base->tid().l4id :
thread_base->native_thread().l4id :
main_thread_tid;
L4_ExchangeRegisters(tid, L4_ExReg_Resume + L4_ExReg_AbortIPC, 0, 0, 0,
@ -72,7 +72,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
Okl4::L4_ThreadId_t tid = thread_base ?
thread_base->tid().l4id :
thread_base->native_thread().l4id :
main_thread_tid;
Okl4::L4_ThreadSwitch(tid);
}
@ -85,7 +85,7 @@ static inline void thread_stop_myself()
{
Genode::Thread_base *myself = Genode::Thread_base::myself();
Okl4::L4_ThreadId_t tid = myself ?
myself->tid().l4id :
myself->native_thread().l4id :
main_thread_tid;
Okl4::L4_Stop(tid);
}

View File

@ -0,0 +1,46 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
/* Genode includes */
#include <base/stdint.h>
/* OKL4 includes */
namespace Okl4 { extern "C" {
#include <l4/types.h>
} }
namespace Genode {
struct Native_thread;
class Platform_thread;
}
struct Genode::Native_thread
{
Okl4::L4_ThreadId_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to
* the physical thread object, which is going to be destroyed
* on destruction of the 'Thread'.
*/
Platform_thread *pt;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -23,8 +23,6 @@ namespace Pistachio {
namespace Genode {
class Platform_thread;
struct Cap_dst_policy
{
typedef Pistachio::L4_ThreadId_t Dst;
@ -37,20 +35,6 @@ namespace Genode {
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
};
struct Native_thread
{
Pistachio::L4_ThreadId_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to
* the physical thread object, which is going to be destroyed
* on destruction of the 'Thread'.
*/
Platform_thread *pt;
};
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
typedef Pistachio::L4_ThreadId_t Native_connection_state;

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Pistachio includes */
namespace Pistachio {
#include <l4/thread.h>
@ -41,13 +44,13 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
void Genode::Thread_base::_thread_bootstrap()
{
_tid.l4id = Pistachio::L4_Myself();
native_thread().l4id = Pistachio::L4_Myself();
}
void Genode::Thread_base::_init_platform_thread(size_t, Type type)
{
if (type == NORMAL) { return; }
_tid.l4id = main_thread_tid;
native_thread().l4id = main_thread_tid;
_thread_cap = env()->parent()->main_thread_cap();
}

View File

@ -15,6 +15,9 @@
#include <base/printf.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* Core includes */
#include <ipc_pager.h>
#include <pager.h>
@ -142,5 +145,5 @@ void Ipc_pager::acknowledge_wakeup()
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
{
return Untyped_capability(_tid.l4id, badge);
return Untyped_capability(native_thread().l4id, badge);
}

View File

@ -37,15 +37,15 @@ void Thread_base::_thread_start()
void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform()->core_mem_alloc())
native_thread().pt = new(platform()->core_mem_alloc())
Platform_thread(0, _stack->name().string());
platform_specific()->core_pd()->bind_thread(_tid.pt);
platform_specific()->core_pd()->bind_thread(native_thread().pt);
_tid.pt->pager(platform_specific()->core_pager());
_tid.l4id = _tid.pt->native_thread_id();
native_thread().pt->pager(platform_specific()->core_pager());
native_thread().l4id = native_thread().pt->native_thread_id();
_tid.pt->start((void *)_thread_start, stack_top());
native_thread().pt->start((void *)_thread_start, stack_top());
}
@ -60,5 +60,5 @@ void Thread_base::cancel_blocking()
void Thread_base::_deinit_platform_thread()
{
/* destruct platform thread */
destroy(platform()->core_mem_alloc(), _tid.pt);
destroy(platform()->core_mem_alloc(), native_thread().pt);
}

View File

@ -55,7 +55,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
L4_ThreadState_t state;
Pistachio::L4_ThreadId_t tid = thread_base ?
thread_base->tid().l4id :
thread_base->native_thread().l4id :
main_thread_tid;
enum { RESUME = 1 << 8, CANCEL_IPC = 3 << 1 };
@ -73,7 +73,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
Pistachio::L4_ThreadId_t tid = thread_base ?
thread_base->tid().l4id :
thread_base->native_thread().l4id :
main_thread_tid;
Pistachio::L4_ThreadSwitch(tid);
}
@ -86,7 +86,7 @@ static inline void thread_stop_myself()
{
Genode::Thread_base *myself = Genode::Thread_base::myself();
Pistachio::L4_ThreadId_t tid = myself ?
myself->tid().l4id :
myself->native_thread().l4id :
main_thread_tid;
Pistachio::L4_Stop(tid);
}

View File

@ -0,0 +1,46 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
/* Genode includes */
#include <base/stdint.h>
/* Pistachio includes */
namespace Pistachio {
#include <l4/types.h>
}
namespace Genode {
class Platform_thread;
struct Native_thread;
}
struct Genode::Native_thread
{
Pistachio::L4_ThreadId_t l4id;
/**
* Only used in core
*
* For 'Thread' objects created within core, 'pt' points to
* the physical thread object, which is going to be destroyed
* on destruction of the 'Thread'.
*/
Platform_thread *pt;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -19,13 +19,6 @@
namespace Genode {
struct Native_thread
{
unsigned tcb_sel = 0;
unsigned ep_sel = 0;
unsigned rcv_sel = 0;
};
class Native_capability
{
public:

View File

@ -14,6 +14,7 @@
/* base includes */
#include <base/native_types.h>
#include <base/printf.h>
#include <util/bit_allocator.h>
/* base-internal includes */
#include <base/internal/capability_data.h>
@ -94,7 +95,7 @@ namespace {
Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread)
{
Cap_sel const ep_sel = Cap_sel(ep_thread.tid().ep_sel);
Cap_sel const ep_sel = Cap_sel(ep_thread.native_thread().ep_sel);
Native_capability::Data &data =
local_capability_space().create_capability(ep_sel, Rpc_obj_key());

View File

@ -44,13 +44,13 @@ enum {
static unsigned &rcv_sel()
{
/*
* When the function is called at the very early initialization phase,
* we cannot access Thread_base::myself()->tid() because the Thread_base
* object of the main thread does not exist yet. During this phase, we
* return a reference to the 'main_rcv_sel' variable.
* When the function is called at the very early initialization phase, we
* cannot access Thread_base::myself()->native_thread() because the
* Thread_base object of the main thread does not exist yet. During this
* phase, we return a reference to the 'main_rcv_sel' variable.
*/
if (Thread_base::myself()) {
return Thread_base::myself()->tid().rcv_sel;
return Thread_base::myself()->native_thread().rcv_sel;
}
static unsigned main_rcv_sel = Capability_space::alloc_rcv_sel();
@ -374,7 +374,7 @@ void Ipc_server::_wait()
{
seL4_Word badge = Rpc_obj_key::INVALID;
seL4_MessageInfo_t const msg_info =
seL4_Recv(Thread_base::myself()->tid().ep_sel, &badge);
seL4_Recv(Thread_base::myself()->native_thread().ep_sel, &badge);
decode_seL4_message(badge, msg_info, *_rcv_msg);
@ -401,7 +401,7 @@ void Ipc_server::_reply_wait()
new_seL4_message(*_snd_msg, _write_offset);
seL4_MessageInfo_t const request_msg_info =
seL4_ReplyRecv(Thread_base::myself()->tid().ep_sel,
seL4_ReplyRecv(Thread_base::myself()->native_thread().ep_sel,
reply_msg_info, &badge);
decode_seL4_message(badge, request_msg_info, *_rcv_msg);

View File

@ -34,7 +34,7 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
void Genode::Thread_base::_thread_bootstrap()
{
if (tid().ep_sel == 0) {
tid().ep_sel = _stack->utcb().ep_sel;
if (native_thread().ep_sel == 0) {
native_thread().ep_sel = _stack->utcb().ep_sel;
}
}

View File

@ -124,7 +124,7 @@ Capability_space::create_rpc_obj_cap(Native_capability ep_cap,
Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread)
{
Cap_sel const ep_sel(ep_thread.tid().ep_sel);
Cap_sel const ep_sel(ep_thread.native_thread().ep_sel);
/* entrypoint capabilities are not allocated from a PD session */
Pd_session const *pd_session = nullptr;

View File

@ -74,11 +74,11 @@ void Ipc_pager::reply_and_wait_for_fault()
seL4_MessageInfo_t const reply_msg = seL4_MessageInfo_new(0, 0, 0, 0);
page_fault_msg_info =
seL4_ReplyRecv(Thread_base::myself()->tid().ep_sel, reply_msg, &badge);
seL4_ReplyRecv(Thread_base::myself()->native_thread().ep_sel, reply_msg, &badge);
} else {
page_fault_msg_info =
seL4_Recv(Thread_base::myself()->tid().ep_sel, &badge);
seL4_Recv(Thread_base::myself()->native_thread().ep_sel, &badge);
}
Fault_info const fault_info(page_fault_msg_info);

View File

@ -32,7 +32,7 @@ void Thread_base::_init_platform_thread(size_t, Type type)
addr_t const utcb_virt_addr = (addr_t)&_stack->utcb();
if (type == MAIN) {
_tid.tcb_sel = seL4_CapInitThreadTCB;
native_thread().tcb_sel = seL4_CapInitThreadTCB;
return;
}
@ -44,13 +44,13 @@ void Thread_base::_init_platform_thread(size_t, Type type)
thread_info.ipc_buffer_phys, utcb_virt_addr);
}
_tid.tcb_sel = thread_info.tcb_sel.value();
_tid.ep_sel = thread_info.ep_sel.value();
native_thread().tcb_sel = thread_info.tcb_sel.value();
native_thread().ep_sel = thread_info.ep_sel.value();
Platform &platform = *platform_specific();
seL4_CapData_t no_cap_data = { { 0 } };
int const ret = seL4_TCB_SetSpace(_tid.tcb_sel, 0,
int const ret = seL4_TCB_SetSpace(native_thread().tcb_sel, 0,
platform.top_cnode().sel().value(), no_cap_data,
seL4_CapInitThreadPD, no_cap_data);
ASSERT(ret == 0);
@ -74,7 +74,7 @@ void Thread_base::_thread_start()
void Thread_base::start()
{
start_sel4_thread(Cap_sel(_tid.tcb_sel), (addr_t)&_thread_start,
start_sel4_thread(Cap_sel(native_thread().tcb_sel), (addr_t)&_thread_start,
(addr_t)stack_top());
}

View File

@ -17,6 +17,9 @@
/* base includes */
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
/* seL4 includes */
#include <sel4/sel4.h>
@ -31,7 +34,7 @@ static inline void kernel_debugger_panic(char const *msg)
{
kernel_debugger_outstring(msg);
kernel_debugger_outstring("\n");
seL4_TCB_Suspend(Genode::Thread_base::myself()->tid().tcb_sel);
seL4_TCB_Suspend(Genode::Thread_base::myself()->native_thread().tcb_sel);
}
#endif /* _INCLUDE__BASE__INTERNAL__KERNEL_DEBUGGER_H_ */

View File

@ -0,0 +1,28 @@
/*
* \brief Kernel-specific thread meta data
* \author Norman Feske
* \date 2016-03-11
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
#include <base/stdint.h>
namespace Genode { struct Native_thread; }
struct Genode::Native_thread
{
unsigned tcb_sel = 0;
unsigned ep_sel = 0;
unsigned rcv_sel = 0;
};
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */

View File

@ -17,19 +17,15 @@
/* Genode includes */
#include <base/exception.h>
#include <base/lock.h>
#include <base/native_types.h>
#include <base/trace/logger.h>
#include <cpu/consts.h>
#include <util/string.h>
#include <util/bit_allocator.h>
#include <ram_session/ram_session.h> /* for 'Ram_dataspace_capability' type */
#include <cpu_session/cpu_session.h> /* for 'Thread_capability' type */
#include <cpu_session/capability.h> /* for 'Cpu_session_capability' type */
namespace Genode {
struct Native_utcb;
class Rm_session;
struct Native_thread;
class Thread_base;
class Stack;
template <unsigned> class Thread;
@ -37,7 +33,7 @@ namespace Genode {
/**
* Concurrent control flow
* Concurrent flow of control
*
* A 'Thread_base' object corresponds to a physical thread. The execution
* starts at the 'entry()' method as soon as 'start()' is called.
@ -91,37 +87,37 @@ class Genode::Thread_base
*
* Used if thread creation involves core's CPU service.
*/
Genode::Thread_capability _thread_cap;
Thread_capability _thread_cap;
/**
* Capability to pager paging this thread (created by _start())
*/
Genode::Pager_capability _pager_cap;
Pager_capability _pager_cap;
/**
* Pointer to cpu session used for this thread
*/
Genode::Cpu_session *_cpu_session;
Cpu_session *_cpu_session = nullptr;
/**
* Base pointer to Trace::Control area used by this thread
*/
Trace::Control *_trace_control;
Trace::Control *_trace_control = nullptr;
/**
* Pointer to primary stack
*/
Stack *_stack;
Stack *_stack = nullptr;
/**
* Physical thread ID
* Pointer to kernel-specific meta data
*/
Native_thread _tid;
Native_thread *_native_thread = nullptr;
/**
* Lock used for synchronizing the finalization of the thread
*/
Genode::Lock _join_lock;
Lock _join_lock;
/**
* Thread type
@ -253,7 +249,7 @@ class Genode::Thread_base
/**
* Request capability of thread
*/
Genode::Thread_capability cap() const { return _thread_cap; }
Thread_capability cap() const { return _thread_cap; }
/**
* Cancel currently blocking operation
@ -261,11 +257,9 @@ class Genode::Thread_base
void cancel_blocking();
/**
* Return thread ID
*
* \noapi Only to be called from platform-specific code
* Return kernel-specific thread meta data
*/
Native_thread & tid() { return _tid; }
Native_thread &native_thread();
/**
* Return top of stack

View File

@ -174,6 +174,9 @@ void Thread_base::free_secondary_stack(void* stack_addr)
}
Native_thread &Thread_base::native_thread() { return _stack->native_thread(); }
void *Thread_base::stack_top() const { return (void *)_stack->top(); }

View File

@ -20,6 +20,7 @@
#include <cpu/memory_barrier.h>
/* base-internal includes */
#include <base/internal/native_thread.h>
#include <base/internal/lock_helper.h>
/*

View File

@ -61,6 +61,7 @@
/* base-internal includes */
#include <base/internal/native_utcb.h>
#include <base/internal/native_thread.h>
namespace Genode { class Stack; }
@ -112,6 +113,11 @@ class Genode::Stack
*/
Ram_dataspace_capability _ds_cap;
/**
* Kernel-specific thread meta data
*/
Native_thread _native_thread;
/*
* <- end of regular memory area
*
@ -157,6 +163,11 @@ class Genode::Stack
*/
void size(size_t const size);
/**
* Return kernel-specific thread meta data
*/
Native_thread &native_thread() { return _native_thread; }
/**
* Return UTCB of the stack's thread
*/

View File

@ -14,6 +14,9 @@
#ifndef _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_
#define _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_
/* Genode includes */
#include <util/bit_allocator.h>
/* base-internal includes */
#include <base/internal/stack.h>
#include <base/internal/stack_area.h>

View File

@ -5,6 +5,7 @@
*/
/* Genode includes */
#include <util/bit_allocator.h>
#include <base/printf.h>
#include <os/attached_io_mem_dataspace.h>
#include <os/config.h>

View File

@ -23,6 +23,8 @@
#include <util/flex_iterator.h>
#include <util/retry.h>
#include <nova/native_thread.h>
#include "../pci_device_pd_ipc.h"
/**
@ -77,7 +79,7 @@ static bool map_eager(Genode::addr_t const page, unsigned log2_order)
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
Nova::Rights const mapping_rw(true, true, false);
addr_t const page_fault_portal = myself->tid().exc_pt_sel + 14;
addr_t const page_fault_portal = myself->native_thread().exc_pt_sel + 14;
/* setup faked page fault information */
utcb->set_msg_word(((addr_t)&utcb->qual[2] - (addr_t)utcb->msg) / sizeof(addr_t));

View File

@ -12,6 +12,7 @@
*/
/* Genode includes */
#include <util/bit_allocator.h>
#include <base/printf.h>
#include <irq_session/connection.h>

View File

@ -11,8 +11,10 @@
* under the terms of the GNU General Public License version 2.
*/
#pragma once
#ifndef _X86_PCI_CONFIG_ACCESS_H_
#define _X86_PCI_CONFIG_ACCESS_H_
#include <util/bit_array.h>
#include <io_port_session/connection.h>
#include <platform_device/platform_device.h>
@ -177,3 +179,5 @@ namespace Platform {
}
};
}
#endif /* _X86_PCI_CONFIG_ACCESS_H_ */

View File

@ -19,6 +19,9 @@
#include <os/server.h>
#include <trace/timestamp.h>
/* NOVA includes */
#include <nova/native_thread.h>
class Platform_timer
{
private:
@ -102,7 +105,7 @@ class Platform_timer
using namespace Nova;
if (_sem == ~0UL)
_sem = blocking_thread->tid().exc_pt_sel + SM_SEL_EC;
_sem = blocking_thread->native_thread().exc_pt_sel + SM_SEL_EC;
addr_t sem = _sem;

View File

@ -21,6 +21,7 @@
#include <base/cap_map.h>
#include <foc_cpu_session/connection.h>
#include <timer_session/connection.h>
#include <foc/native_thread.h>
namespace Fiasco {
#include <l4/sys/utcb.h>
@ -64,7 +65,7 @@ namespace L4lx {
start();
/* set l4linux specific utcb entry: L4X_UTCB_TCR_ID */
l4_utcb_tcr_u(_utcb)->user[0] = tid().kcap;
l4_utcb_tcr_u(_utcb)->user[0] = native_thread().kcap;
/* enable vcpu functionality respectively */
if (_vcpu_state)

View File

@ -212,7 +212,7 @@ l4_cap_idx_t l4lx_thread_get_cap(l4lx_thread_t t)
PWRN("Invalid utcb %lx", (unsigned long) t);
return L4_INVALID_CAP;
}
return vcpus[thread_id(t)]->tid().kcap;
return vcpus[thread_id(t)]->native_thread().kcap;
}

View File

@ -80,7 +80,7 @@ class Vmm::Vcpu_dispatcher : public T
cpu_session->affinity(T::cap(), location);
/* request creation of a 'local' EC */
T::_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
T::start();
}
@ -99,7 +99,7 @@ class Vmm::Vcpu_dispatcher : public T
cpu_session->affinity(T::cap(), location);
/* request creation of a 'local' EC */
T::_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
T::start();
}
@ -117,7 +117,7 @@ class Vmm::Vcpu_dispatcher : public T
/* Create the portal at the desired selector index */
_native_pd.rcv_window(exc_base + EV);
Native_capability thread_cap(T::tid().ec_sel);
Native_capability thread_cap(T::native_thread().ec_sel);
Untyped_capability handler =
retry<Genode::Pd_session::Out_of_metadata>(
@ -158,7 +158,7 @@ class Vmm::Vcpu_dispatcher : public T
*/
Nova::mword_t sel_sm_ec()
{
return T::tid().exc_pt_sel + Nova::SM_SEL_EC;
return T::native_thread().exc_pt_sel + Nova::SM_SEL_EC;
}
};

View File

@ -23,6 +23,9 @@
#include <pd_session/connection.h>
#include <rm_session/connection.h>
/* NOVA includes */
#include <nova/native_thread.h>
namespace Vmm {
using namespace Genode;
@ -118,13 +121,13 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base
Thread_base(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session)
{
/* release pre-allocated selectors of Thread */
Genode::cap_map()->remove(tid().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
Genode::cap_map()->remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
/* allocate correct number of selectors */
this->tid().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2);
this->native_thread().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2);
/* tell generic thread code that this becomes a vCPU */
this->tid().is_vcpu = true;
this->native_thread().is_vcpu = true;
/* place the thread on CPU described by location object */
cpu_session->affinity(Thread_base::cap(), location);
@ -134,14 +137,14 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base
{
using namespace Nova;
revoke(Nova::Obj_crd(this->tid().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2));
cap_map()->remove(this->tid().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2, false);
revoke(Nova::Obj_crd(this->native_thread().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2));
cap_map()->remove(this->native_thread().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2, false);
/* allocate selectors for ~Thread */
this->tid().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_PT_LOG2);
this->native_thread().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_PT_LOG2);
}
addr_t exc_base() { return this->tid().exc_pt_sel; }
addr_t exc_base() { return this->native_thread().exc_pt_sel; }
void start(Genode::addr_t sel_ec)
{

View File

@ -197,7 +197,7 @@ void genode_update_tsc(void (*update_func)(void), unsigned long update_us)
enum { TSC_FACTOR = 1000ULL };
Genode::addr_t sem = Thread_base::myself()->tid().exc_pt_sel + Nova::SM_SEL_EC;
Genode::addr_t sem = Thread_base::myself()->native_thread().exc_pt_sel + Nova::SM_SEL_EC;
unsigned long tsc_khz = (genode_cpu_hz() / 1000) / TSC_FACTOR;
Trace::Timestamp us_64 = update_us;