diff --git a/repos/base-fiasco/include/base/native_types.h b/repos/base-fiasco/include/base/native_types.h index 86705eb556..3ee6ea8f5b 100644 --- a/repos/base-fiasco/include/base/native_types.h +++ b/repos/base-fiasco/include/base/native_types.h @@ -38,20 +38,6 @@ namespace Genode { static void copy(void* dst, Native_capability_tpl* 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 Native_capability; typedef Fiasco::l4_threadid_t Native_connection_state; } diff --git a/repos/base-fiasco/src/core/pager.cc b/repos/base-fiasco/src/core/pager.cc index b300ac60d2..6ba1628107 100644 --- a/repos/base-fiasco/src/core/pager.cc +++ b/repos/base-fiasco/src/core/pager.cc @@ -14,10 +14,13 @@ /* Genode includes */ #include -/* Core includes */ +/* core includes */ #include #include +/* base-internal includes */ +#include + namespace Fiasco { #include #include @@ -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); } diff --git a/repos/base-fiasco/src/core/thread_start.cc b/repos/base-fiasco/src/core/thread_start.cc index 9dad277559..09a6ae8ecf 100644 --- a/repos/base-fiasco/src/core/thread_start.cc +++ b/repos/base-fiasco/src/core/thread_start.cc @@ -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); } diff --git a/repos/base-fiasco/src/include/base/internal/native_thread.h b/repos/base-fiasco/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..454e65c2bb --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/native_thread.h @@ -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 + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +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_ */ diff --git a/repos/base-foc/include/base/native_types.h b/repos/base-foc/include/base/native_types.h index 4c9d8192b5..9160f70312 100644 --- a/repos/base-foc/include/base/native_types.h +++ b/repos/base-foc/include/base/native_types.h @@ -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; diff --git a/repos/base-foc/include/foc/native_thread.h b/repos/base-foc/include/foc/native_thread.h new file mode 100644 index 0000000000..c293885630 --- /dev/null +++ b/repos/base-foc/include/foc/native_thread.h @@ -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 + +/* Fiasco.OC includes */ +namespace Fiasco { +#include +} + +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_ */ diff --git a/repos/base-foc/include/signal_source/client.h b/repos/base-foc/include/signal_source/client.h index 83f20f67bb..16be3fdef2 100644 --- a/repos/base-foc/include/signal_source/client.h +++ b/repos/base-foc/include/signal_source/client.h @@ -27,6 +27,9 @@ #include #include +/* base-internal includes */ +#include + namespace Fiasco { #include } @@ -53,7 +56,7 @@ namespace Genode { _sem = call(); 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)); } diff --git a/repos/base-foc/src/base/thread/thread_start.cc b/repos/base-foc/src/base/thread/thread_start.cc index 90ffb61cbd..c44b2076d2 100644 --- a/repos/base-foc/src/base/thread/thread_start.cc +++ b/repos/base-foc/src/base/thread/thread_start.cc @@ -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; diff --git a/repos/base-foc/src/core/include/cap_index.h b/repos/base-foc/src/core/include/cap_index.h index f5340faf96..a9d149ec3e 100644 --- a/repos/base-foc/src/core/include/cap_index.h +++ b/repos/base-foc/src/core/include/cap_index.h @@ -17,6 +17,9 @@ /* Genode includes */ #include +/* base-internal includes */ +#include + namespace Genode { class Platform_thread; diff --git a/repos/base-foc/src/core/include/ipc_pager.h b/repos/base-foc/src/core/include/ipc_pager.h index 6c6a56c0c2..17ecc1fd15 100644 --- a/repos/base-foc/src/core/include/ipc_pager.h +++ b/repos/base-foc/src/core/include/ipc_pager.h @@ -23,6 +23,9 @@ #include #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include diff --git a/repos/base-foc/src/core/pager.cc b/repos/base-foc/src/core/pager.cc index 722c4f1807..e3602554bd 100644 --- a/repos/base-foc/src/core/pager.cc +++ b/repos/base-foc/src/core/pager.cc @@ -18,9 +18,12 @@ #include #include -/* Core includes */ +/* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco.OC includes */ namespace Fiasco { #include diff --git a/repos/base-foc/src/core/thread_start.cc b/repos/base-foc/src/core/thread_start.cc index 1338156ce5..7fc88f5bd8 100644 --- a/repos/base-foc/src/core/thread_start.cc +++ b/repos/base-foc/src/core/thread_start.cc @@ -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; diff --git a/repos/base-foc/src/include/base/internal/lock_helper.h b/repos/base-foc/src/include/base/internal/lock_helper.h index 4ab55505ab..2377d8a031 100644 --- a/repos/base-foc/src/include/base/internal/lock_helper.h +++ b/repos/base-foc/src/include/base/internal/lock_helper.h @@ -22,6 +22,9 @@ #include #include +/* base-internal includes */ +#include + /* Fiasco.OC includes */ namespace Fiasco { #include @@ -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); diff --git a/repos/base-foc/src/include/base/internal/native_thread.h b/repos/base-foc/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..b27dad6893 --- /dev/null +++ b/repos/base-foc/src/include/base/internal/native_thread.h @@ -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 diff --git a/repos/base-hw/include/base/native_types.h b/repos/base-hw/include/base/native_types.h index 0e1359161d..6ae9e600de 100644 --- a/repos/base-hw/include/base/native_types.h +++ b/repos/base-hw/include/base/native_types.h @@ -15,32 +15,11 @@ #ifndef _INCLUDE__BASE__NATIVE_TYPES_H_ #define _INCLUDE__BASE__NATIVE_TYPES_H_ -/* Genode includes */ -#include #include -#include -#include 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_ */ diff --git a/repos/base-hw/src/base/ipc/ipc.cc b/repos/base-hw/src/base/ipc/ipc.cc index 2d3b78299e..665f1e0d1d 100644 --- a/repos/base-hw/src/base/ipc/ipc.cc +++ b/repos/base-hw/src/base/ipc/ipc.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include +#include /* base-hw includes */ #include @@ -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(RPC_OBJECT_ID_SIZE); } diff --git a/repos/base-hw/src/base/thread/bootstrap.cc b/repos/base-hw/src/base/thread/bootstrap.cc index 1b8645e7d0..3e9d474d11 100644 --- a/repos/base-hw/src/base/thread/bootstrap.cc +++ b/repos/base-hw/src/base/thread/bootstrap.cc @@ -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); } diff --git a/repos/base-hw/src/base/thread/start.cc b/repos/base-hw/src/base/thread/start.cc index 5ae364ba40..58019cec74 100644 --- a/repos/base-hw/src/base/thread/start.cc +++ b/repos/base-hw/src/base/thread/start.cc @@ -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(); } diff --git a/repos/base-hw/src/core/thread_start.cc b/repos/base-hw/src/core/thread_start.cc index c2a0c25865..704daaf9cf 100644 --- a/repos/base-hw/src/core/thread_start.cc +++ b/repos/base-hw/src/core/thread_start.cc @@ -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(); } diff --git a/repos/base-hw/src/include/base/internal/lock_helper.h b/repos/base-hw/src/include/base/internal/lock_helper.h index 994feafc9d..8c33d99232 100644 --- a/repos/base-hw/src/include/base/internal/lock_helper.h +++ b/repos/base-hw/src/include/base/internal/lock_helper.h @@ -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(); } diff --git a/repos/base-hw/src/include/base/internal/native_thread.h b/repos/base-hw/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..600b4a16e6 --- /dev/null +++ b/repos/base-hw/src/include/base/internal/native_thread.h @@ -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 +#include + +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_ */ diff --git a/repos/base-linux/include/base/native_types.h b/repos/base-linux/include/base/native_types.h index e4a3c5f478..affcd24320 100644 --- a/repos/base-linux/include/base/native_types.h +++ b/repos/base-linux/include/base/native_types.h @@ -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 diff --git a/repos/base-linux/src/base/ipc/ipc.cc b/repos/base-linux/src/base/ipc/ipc.cc index 55a331660f..e5ed718003 100644 --- a/repos/base-linux/src/base/ipc/ipc.cc +++ b/repos/base-linux/src/base/ipc/ipc.cc @@ -36,6 +36,7 @@ /* base-internal includes */ #include +#include /* Linux includes */ #include @@ -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' */ diff --git a/repos/base-linux/src/base/thread/thread_linux.cc b/repos/base-linux/src/base/thread/thread_linux.cc index 07fbc26fd1..cabb4ad4ce 100644 --- a/repos/base-linux/src/base/thread/thread_linux.cc +++ b/repos/base-linux/src/base/thread/thread_linux.cc @@ -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(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(); diff --git a/repos/base-linux/src/core/platform.cc b/repos/base-linux/src/core/platform.cc index 66fa84c881..dd759c2db5 100644 --- a/repos/base-linux/src/core/platform.cc +++ b/repos/base-linux/src/core/platform.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* 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) diff --git a/repos/base-linux/src/core/thread_linux.cc b/repos/base-linux/src/core/thread_linux.cc index 4e5c248b32..a30f704825 100644 --- a/repos/base-linux/src/core/thread_linux.cc +++ b/repos/base-linux/src/core/thread_linux.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* Linux syscall bindings */ #include @@ -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(); } diff --git a/repos/base-linux/src/include/base/internal/lock_helper.h b/repos/base-linux/src/include/base/internal/lock_helper.h index 64398a5f62..4f59644f47 100644 --- a/repos/base-linux/src/include/base/internal/lock_helper.h +++ b/repos/base-linux/src/include/base/internal/lock_helper.h @@ -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); } diff --git a/repos/base-linux/src/include/base/internal/native_thread.h b/repos/base-linux/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..5cd901dda6 --- /dev/null +++ b/repos/base-linux/src/include/base/internal/native_thread.h @@ -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 + +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_ */ diff --git a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc index 750e8bcec7..95f72e7b50 100644 --- a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc +++ b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc @@ -11,11 +11,14 @@ * under the terms of the GNU General Public License version 2. */ -//#include +/* Genode includes */ #include #include #include +/* base-internal includes */ +#include + 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(_tid.meta_data); + dynamic_cast(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); diff --git a/repos/base-nova/include/base/native_types.h b/repos/base-nova/include/base/native_types.h index 477d570a7f..bd172a3252 100644 --- a/repos/base-nova/include/base/native_types.h +++ b/repos/base-nova/include/base/native_types.h @@ -15,27 +15,16 @@ #ifndef _INCLUDE__BASE__NATIVE_TYPES_H_ #define _INCLUDE__BASE__NATIVE_TYPES_H_ +/* Genode includes */ #include #include - -#include - #include +/* NOVA includes */ +#include + 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: diff --git a/repos/base-nova/include/nova/native_thread.h b/repos/base-nova/include/nova/native_thread.h new file mode 100644 index 0000000000..d74ef62315 --- /dev/null +++ b/repos/base-nova/include/nova/native_thread.h @@ -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 + +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_ */ diff --git a/repos/base-nova/include/signal_source/client.h b/repos/base-nova/include/signal_source/client.h index 13794da417..484f550cda 100644 --- a/repos/base-nova/include/signal_source/client.h +++ b/repos/base-nova/include/signal_source/client.h @@ -21,9 +21,13 @@ #ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ #define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ +/* Genode includes */ #include #include +/* base-internal includes */ +#include + /* NOVA includes */ #include #include @@ -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(_sem); } diff --git a/repos/base-nova/src/base/server/server.cc b/repos/base-nova/src/base/server/server.cc index ee5a1e1770..7d4fb28cb2 100644 --- a/repos/base-nova/src/base/server/server.cc +++ b/repos/base-nova/src/base/server/server.cc @@ -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(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(); diff --git a/repos/base-nova/src/base/sleep.cc b/repos/base-nova/src/base/sleep.cc index 08bb47d6f1..e6b6174797 100644 --- a/repos/base-nova/src/base/sleep.cc +++ b/repos/base-nova/src/base/sleep.cc @@ -16,6 +16,9 @@ #include #include +/* base-internal includes */ +#include + /* NOVA includes */ #include #include @@ -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)) diff --git a/repos/base-nova/src/base/thread/thread_nova.cc b/repos/base-nova/src/base/thread/thread_nova.cc index f91049387e..2e652a03aa 100644 --- a/repos/base-nova/src/base/thread/thread_nova.cc +++ b/repos/base-nova/src/base/thread/thread_nova.cc @@ -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_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(&_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(_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()); @@ -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(); } diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index b1626b3602..3f4e656d48 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -18,6 +18,9 @@ #include #include +/* base-internal includes */ +#include + /* core-local includes */ #include #include @@ -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); @@ -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(_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 = diff --git a/repos/base-nova/src/core/thread_start.cc b/repos/base-nova/src/core/thread_start.cc index d648428f88..c2fb4518a3 100644 --- a/repos/base-nova/src/core/thread_start.cc +++ b/repos/base-nova/src/core/thread_start.cc @@ -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(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(); } diff --git a/repos/base-nova/src/include/base/internal/lock_helper.h b/repos/base-nova/src/include/base/internal/lock_helper.h index 7e4f9f6426..7379868ad8 100644 --- a/repos/base-nova/src/include/base/internal/lock_helper.h +++ b/repos/base-nova/src/include/base/internal/lock_helper.h @@ -23,6 +23,9 @@ #include #include +/* base-internal includes */ +#include + /* NOVA includes */ #include #include @@ -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(); diff --git a/repos/base-nova/src/include/base/internal/native_thread.h b/repos/base-nova/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..451a28b944 --- /dev/null +++ b/repos/base-nova/src/include/base/internal/native_thread.h @@ -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 diff --git a/repos/base-nova/src/include/base/internal/spin_lock.h b/repos/base-nova/src/include/base/internal/spin_lock.h index d387a2bc8d..a0c1e4dd2b 100644 --- a/repos/base-nova/src/include/base/internal/spin_lock.h +++ b/repos/base-nova/src/include/base/internal/spin_lock.h @@ -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; diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index 735fa9643e..b953f72cad 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -23,6 +23,7 @@ #include #include +#include #include "server.h" @@ -199,7 +200,7 @@ class Greedy : public Thread<4096> { Nova::Utcb * nova_utcb = reinterpret_cast(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); } diff --git a/repos/base-okl4/include/base/native_types.h b/repos/base-okl4/include/base/native_types.h index d109f7ac65..5580a27f5e 100644 --- a/repos/base-okl4/include/base/native_types.h +++ b/repos/base-okl4/include/base/native_types.h @@ -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 { diff --git a/repos/base-okl4/src/base/thread/thread_bootstrap.cc b/repos/base-okl4/src/base/thread/thread_bootstrap.cc index 74ef42c0e8..99357bf73f 100644 --- a/repos/base-okl4/src/base/thread/thread_bootstrap.cc +++ b/repos/base-okl4/src/base/thread/thread_bootstrap.cc @@ -16,14 +16,14 @@ #include #include +/* base-internal includes */ +#include + /* OKL4 includes */ -namespace Okl4 -{ - extern "C" { - #include - #include - } -} +namespace Okl4 { extern "C" { +#include +#include +} } 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(); } diff --git a/repos/base-okl4/src/core/pager.cc b/repos/base-okl4/src/core/pager.cc index 6af8e08a0b..f740bbce27 100644 --- a/repos/base-okl4/src/core/pager.cc +++ b/repos/base-okl4/src/core/pager.cc @@ -19,6 +19,9 @@ #include #include +/* base-internal includes */ +#include + namespace Okl4 { extern "C" { #include #include @@ -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); } diff --git a/repos/base-okl4/src/core/thread_start.cc b/repos/base-okl4/src/core/thread_start.cc index 02a01b6797..b2978f9aba 100644 --- a/repos/base-okl4/src/core/thread_start.cc +++ b/repos/base-okl4/src/core/thread_start.cc @@ -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); } diff --git a/repos/base-okl4/src/include/base/internal/lock_helper.h b/repos/base-okl4/src/include/base/internal/lock_helper.h index 056e0591de..077a5c432b 100644 --- a/repos/base-okl4/src/include/base/internal/lock_helper.h +++ b/repos/base-okl4/src/include/base/internal/lock_helper.h @@ -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); } diff --git a/repos/base-okl4/src/include/base/internal/native_thread.h b/repos/base-okl4/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..d680eaf42e --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/native_thread.h @@ -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 + +/* OKL4 includes */ +namespace Okl4 { extern "C" { +#include +} } + +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_ */ diff --git a/repos/base-pistachio/include/base/native_types.h b/repos/base-pistachio/include/base/native_types.h index f56241e096..e22afa270a 100644 --- a/repos/base-pistachio/include/base/native_types.h +++ b/repos/base-pistachio/include/base/native_types.h @@ -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* 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 Native_capability; typedef Pistachio::L4_ThreadId_t Native_connection_state; diff --git a/repos/base-pistachio/src/base/thread/thread_bootstrap.cc b/repos/base-pistachio/src/base/thread/thread_bootstrap.cc index 9175c9d174..1cad1ee109 100644 --- a/repos/base-pistachio/src/base/thread/thread_bootstrap.cc +++ b/repos/base-pistachio/src/base/thread/thread_bootstrap.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* Pistachio includes */ namespace Pistachio { #include @@ -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(); } diff --git a/repos/base-pistachio/src/core/pager.cc b/repos/base-pistachio/src/core/pager.cc index 6918337e9d..c0f79c88ff 100644 --- a/repos/base-pistachio/src/core/pager.cc +++ b/repos/base-pistachio/src/core/pager.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* Core includes */ #include #include @@ -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); } diff --git a/repos/base-pistachio/src/core/thread_start.cc b/repos/base-pistachio/src/core/thread_start.cc index 9dad277559..09a6ae8ecf 100644 --- a/repos/base-pistachio/src/core/thread_start.cc +++ b/repos/base-pistachio/src/core/thread_start.cc @@ -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); } diff --git a/repos/base-pistachio/src/include/base/internal/lock_helper.h b/repos/base-pistachio/src/include/base/internal/lock_helper.h index e3affa25b7..eef5fe3be4 100644 --- a/repos/base-pistachio/src/include/base/internal/lock_helper.h +++ b/repos/base-pistachio/src/include/base/internal/lock_helper.h @@ -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); } diff --git a/repos/base-pistachio/src/include/base/internal/native_thread.h b/repos/base-pistachio/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..dc09902085 --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/native_thread.h @@ -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 + +/* Pistachio includes */ +namespace Pistachio { +#include +} + +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_ */ diff --git a/repos/base-sel4/include/base/native_types.h b/repos/base-sel4/include/base/native_types.h index 32804afa72..55a1154d6a 100644 --- a/repos/base-sel4/include/base/native_types.h +++ b/repos/base-sel4/include/base/native_types.h @@ -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: diff --git a/repos/base-sel4/src/base/env/capability_space.cc b/repos/base-sel4/src/base/env/capability_space.cc index 4e5d60e442..fc4da8df78 100644 --- a/repos/base-sel4/src/base/env/capability_space.cc +++ b/repos/base-sel4/src/base/env/capability_space.cc @@ -14,6 +14,7 @@ /* base includes */ #include #include +#include /* base-internal includes */ #include @@ -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()); diff --git a/repos/base-sel4/src/base/ipc/ipc.cc b/repos/base-sel4/src/base/ipc/ipc.cc index 91f3999b94..09c3c71d10 100644 --- a/repos/base-sel4/src/base/ipc/ipc.cc +++ b/repos/base-sel4/src/base/ipc/ipc.cc @@ -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); diff --git a/repos/base-sel4/src/base/thread/thread_bootstrap.cc b/repos/base-sel4/src/base/thread/thread_bootstrap.cc index ea0cf35ce7..742ba05fe8 100644 --- a/repos/base-sel4/src/base/thread/thread_bootstrap.cc +++ b/repos/base-sel4/src/base/thread/thread_bootstrap.cc @@ -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; } } diff --git a/repos/base-sel4/src/core/capability_space.cc b/repos/base-sel4/src/core/capability_space.cc index 79fd322bea..e1546975fe 100644 --- a/repos/base-sel4/src/core/capability_space.cc +++ b/repos/base-sel4/src/core/capability_space.cc @@ -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; diff --git a/repos/base-sel4/src/core/pager.cc b/repos/base-sel4/src/core/pager.cc index 3603d1460a..9c67fcab1e 100644 --- a/repos/base-sel4/src/core/pager.cc +++ b/repos/base-sel4/src/core/pager.cc @@ -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); diff --git a/repos/base-sel4/src/core/thread_start.cc b/repos/base-sel4/src/core/thread_start.cc index d2b331d1a9..f0b6ea73c2 100644 --- a/repos/base-sel4/src/core/thread_start.cc +++ b/repos/base-sel4/src/core/thread_start.cc @@ -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()); } diff --git a/repos/base-sel4/src/include/base/internal/kernel_debugger.h b/repos/base-sel4/src/include/base/internal/kernel_debugger.h index c238e86fc2..47b779a1a5 100644 --- a/repos/base-sel4/src/include/base/internal/kernel_debugger.h +++ b/repos/base-sel4/src/include/base/internal/kernel_debugger.h @@ -17,6 +17,9 @@ /* base includes */ #include +/* base-internal includes */ +#include + /* seL4 includes */ #include @@ -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_ */ diff --git a/repos/base-sel4/src/include/base/internal/native_thread.h b/repos/base-sel4/src/include/base/internal/native_thread.h new file mode 100644 index 0000000000..ff9c96af66 --- /dev/null +++ b/repos/base-sel4/src/include/base/internal/native_thread.h @@ -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 + +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_ */ diff --git a/repos/base/include/base/thread.h b/repos/base/include/base/thread.h index e3d1f1fe01..ec27e6ac6b 100644 --- a/repos/base/include/base/thread.h +++ b/repos/base/include/base/thread.h @@ -17,19 +17,15 @@ /* Genode includes */ #include #include -#include #include #include #include -#include #include /* for 'Ram_dataspace_capability' type */ #include /* for 'Thread_capability' type */ -#include /* for 'Cpu_session_capability' type */ namespace Genode { - struct Native_utcb; - class Rm_session; + struct Native_thread; class Thread_base; class Stack; template 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 diff --git a/repos/base/src/base/thread/thread.cc b/repos/base/src/base/thread/thread.cc index 9c97cfc378..19c056d97a 100644 --- a/repos/base/src/base/thread/thread.cc +++ b/repos/base/src/base/thread/thread.cc @@ -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(); } diff --git a/repos/base/src/include/base/internal/spin_lock.h b/repos/base/src/include/base/internal/spin_lock.h index 44cfea3c1b..bce7834018 100644 --- a/repos/base/src/include/base/internal/spin_lock.h +++ b/repos/base/src/include/base/internal/spin_lock.h @@ -20,6 +20,7 @@ #include /* base-internal includes */ +#include #include /* diff --git a/repos/base/src/include/base/internal/stack.h b/repos/base/src/include/base/internal/stack.h index 9f7aa464d5..7a21eaef7f 100644 --- a/repos/base/src/include/base/internal/stack.h +++ b/repos/base/src/include/base/internal/stack.h @@ -61,6 +61,7 @@ /* base-internal includes */ #include +#include 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 */ diff --git a/repos/base/src/include/base/internal/stack_allocator.h b/repos/base/src/include/base/internal/stack_allocator.h index d63d1f4acc..1f80a954b0 100644 --- a/repos/base/src/include/base/internal/stack_allocator.h +++ b/repos/base/src/include/base/internal/stack_allocator.h @@ -14,6 +14,9 @@ #ifndef _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_ #define _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_ +/* Genode includes */ +#include + /* base-internal includes */ #include #include diff --git a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc index a171cec103..22c773e4a7 100644 --- a/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc +++ b/repos/dde_linux/src/drivers/framebuffer/intel/lx_emul.cc @@ -5,6 +5,7 @@ */ /* Genode includes */ +#include #include #include #include diff --git a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc index f2633bd0c4..ddcd6774fc 100644 --- a/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc +++ b/repos/os/src/drivers/platform/spec/x86/device_pd/main.cc @@ -23,6 +23,8 @@ #include #include +#include + #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(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)); diff --git a/repos/os/src/drivers/platform/spec/x86/irq.cc b/repos/os/src/drivers/platform/spec/x86/irq.cc index 849d88e75b..b18d760d8a 100644 --- a/repos/os/src/drivers/platform/spec/x86/irq.cc +++ b/repos/os/src/drivers/platform/spec/x86/irq.cc @@ -12,6 +12,7 @@ */ /* Genode includes */ +#include #include #include diff --git a/repos/os/src/drivers/platform/spec/x86/pci_config_access.h b/repos/os/src/drivers/platform/spec/x86/pci_config_access.h index ec8c7dd053..f90be5a8eb 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_config_access.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_config_access.h @@ -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 #include #include @@ -177,3 +179,5 @@ namespace Platform { } }; } + +#endif /* _X86_PCI_CONFIG_ACCESS_H_ */ diff --git a/repos/os/src/drivers/timer/spec/nova/platform_timer.h b/repos/os/src/drivers/timer/spec/nova/platform_timer.h index 36784b5d3e..647f4fabfb 100644 --- a/repos/os/src/drivers/timer/spec/nova/platform_timer.h +++ b/repos/os/src/drivers/timer/spec/nova/platform_timer.h @@ -19,6 +19,9 @@ #include #include +/* NOVA includes */ +#include + 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; diff --git a/repos/ports-foc/src/lib/l4lx/include/vcpu.h b/repos/ports-foc/src/lib/l4lx/include/vcpu.h index f0ab185e04..0f805a2ab2 100644 --- a/repos/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/repos/ports-foc/src/lib/l4lx/include/vcpu.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace Fiasco { #include @@ -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) diff --git a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc index 3d622dd1b8..7bd0361daf 100644 --- a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc +++ b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc @@ -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; } diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 427eb92c15..2ebcf1c54c 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -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( @@ -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; } }; diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index f43bdfb238..ea2d68f09a 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -23,6 +23,9 @@ #include #include +/* NOVA includes */ +#include + 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) { diff --git a/repos/ports/src/virtualbox/spec/nova/sup.cc b/repos/ports/src/virtualbox/spec/nova/sup.cc index b54e706f97..073c0f696c 100644 --- a/repos/ports/src/virtualbox/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox/spec/nova/sup.cc @@ -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;