From 99c649c42f1147a126be6d38c2c86279a15a00e1 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 18 Nov 2013 15:31:54 +0100 Subject: [PATCH] hw: simplify Kernel::new_thread Don't set priority and label in platform thread and then communicate this core object via Kernel::new_thread but communicate priority and label directly. This way kernel doesn't need to know anymore what a platform thread is. ref #953 --- base-hw/include/kernel/interface.h | 23 ++++---- base-hw/src/core/include/platform_thread.h | 40 +++++++------ base-hw/src/core/kernel/kernel.cc | 4 +- base-hw/src/core/kernel/thread.cc | 42 +++++-------- base-hw/src/core/kernel/thread.h | 29 ++++----- base-hw/src/core/platform_thread.cc | 68 ++++++++++++---------- 6 files changed, 99 insertions(+), 107 deletions(-) diff --git a/base-hw/include/kernel/interface.h b/base-hw/include/kernel/interface.h index 6bd2a41b25..a67eae1640 100644 --- a/base-hw/include/kernel/interface.h +++ b/base-hw/include/kernel/interface.h @@ -20,7 +20,6 @@ namespace Genode { class Native_utcb; - class Platform_thread; class Platform_pd; class Tlb; } @@ -30,7 +29,6 @@ namespace Kernel typedef Genode::Tlb Tlb; typedef Genode::addr_t addr_t; typedef Genode::size_t size_t; - typedef Genode::Platform_thread Platform_thread; typedef Genode::Platform_pd Platform_pd; typedef Genode::Native_utcb Native_utcb; @@ -200,21 +198,22 @@ namespace Kernel /** - * Create a new thread that is stopped initially + * Create kernel object that acts as thread that isn't executed initially * - * \param dst physical base of an appropriate portion of memory - * that is thereupon allocated to the kernel - * \param pt assigned platform thread + * \param p memory donation for the new kernel thread object + * \param priority scheduling priority of the new thread + * \param label debugging label of the new thread * - * \retval >0 ID of the new thread - * \retval 0 if no new thread was created + * \retval >0 kernel name of the new thread + * \retval 0 failed * - * Restricted to core threads. Regaining of the supplied memory can be done - * through 'delete_thread'. + * Restricted to core threads. */ - inline int new_thread(void * const dst, Platform_thread * const pt) + inline int new_thread(void * const p, unsigned const priority, + char const * const label) { - return call(Call_id::NEW_THREAD, (Call_arg)dst, (Call_arg)pt); + return call((Call_arg)Call_id::NEW_THREAD, (Call_arg)p, (Call_arg)priority, + (Call_arg)label); } diff --git a/base-hw/src/core/include/platform_thread.h b/base-hw/src/core/include/platform_thread.h index dacae70a96..f5dcf7ebaf 100644 --- a/base-hw/src/core/include/platform_thread.h +++ b/base-hw/src/core/include/platform_thread.h @@ -40,7 +40,7 @@ namespace Genode { */ class Platform_thread { - enum { NAME_MAX_LEN = 32 }; + enum { LABEL_MAX_LEN = 32 }; Thread_base * _thread_base; size_t _stack_size; @@ -52,9 +52,8 @@ namespace Genode { Native_utcb * _utcb_virt; Tlb * _tlb; Ram_dataspace_capability _utcb; - char _name[NAME_MAX_LEN]; + char _label[LABEL_MAX_LEN]; char _kernel_thread[sizeof(Kernel::Thread)]; - unsigned _priority; /* * Wether this thread is the main thread of a program. @@ -80,14 +79,24 @@ namespace Genode { /** * Constructor for core threads + * + * \param label debugging label + * \param thread_base Genode thread object + * \param stack_size initial size of the stack + * \param pd_id kernel name of targeted protection domain */ - Platform_thread(const char * name, Thread_base * const thread_base, + Platform_thread(const char * const label, + Thread_base * const thread_base, size_t const stack_size, unsigned const pd_id); /** * Constructor for threads outside of core + * + * \param label debugging label + * \param priority processor-scheduling priority + * \param utcb core local pointer to userland thread-context */ - Platform_thread(const char * name, unsigned const priority, + Platform_thread(const char * const label, unsigned const priority, addr_t const utcb); /** @@ -96,13 +105,14 @@ namespace Genode { ~Platform_thread(); /** - * Join PD identified by 'pd_id' + * Join a protection domain * - * \param pd_id ID of targeted PD - * \param main_thread wether we are the main thread in this PD + * \param pd_id kernel name of targeted protection domain + * \param main_thread wether thread is the first in protection domain + * \param address_space corresponding Genode address space * - * \retval 0 on success - * \retval <0 otherwise + * \retval 0 succeeded + * \retval -1 failed */ int join_pd(unsigned const pd_id, bool const main_thread, Weak_ptr address_space); @@ -166,8 +176,6 @@ namespace Genode { ** Accessors ** ***************/ - inline char const * name() const { return _name; } - void pager(Pager_object * const pager); Pager_object * pager(); @@ -180,7 +188,7 @@ namespace Genode { Thread_base * thread_base() { - if (!_thread_base && !main_thread()) { + if (!_thread_base && !_main_thread) { PERR("invalid thread base"); } return _thread_base; @@ -188,15 +196,9 @@ namespace Genode { Native_utcb * utcb_phys() const { return _utcb_phys; } - Native_utcb * utcb_virt() const { return _utcb_virt; } - Ram_dataspace_capability utcb() const { return _utcb; } - bool main_thread() const { return _main_thread; } - Tlb * tlb() const { return _tlb; } - - unsigned priority() { return _priority; } }; } diff --git a/base-hw/src/core/kernel/kernel.cc b/base-hw/src/core/kernel/kernel.cc index f0e94753b0..f3fd33ff33 100644 --- a/base-hw/src/core/kernel/kernel.cc +++ b/base-hw/src/core/kernel/kernel.cc @@ -115,7 +115,7 @@ namespace Kernel /* create idle thread */ static char idle_stack[DEFAULT_STACK_SIZE] __attribute__((aligned(Cpu::DATA_ACCESS_ALIGNM))); - static Thread idle((Platform_thread *)0); + static Thread idle(Priority::MAX, "idle"); static bool init = 0; if (!init) { enum { STACK_SIZE = sizeof(idle_stack)/sizeof(idle_stack[0]) }; @@ -233,7 +233,7 @@ extern "C" void kernel() /* start thread with stack pointer at the top of stack */ static Native_utcb utcb; _main_utcb = &utcb; - static Thread t((Platform_thread *)0); + static Thread t(Priority::MAX, "core"); t.ip = (addr_t)CORE_MAIN;; t.sp = (addr_t)s + STACK_SIZE; t.init(0, core_id(), &utcb, 1); diff --git a/base-hw/src/core/kernel/thread.cc b/base-hw/src/core/kernel/thread.cc index 60396918e2..663b4147ac 100644 --- a/base-hw/src/core/kernel/thread.cc +++ b/base-hw/src/core/kernel/thread.cc @@ -21,7 +21,6 @@ #include #include #include -#include #include using namespace Kernel; @@ -184,15 +183,15 @@ void Thread::_schedule() } -Thread::Thread(Platform_thread * const pt) +Thread::Thread(unsigned const priority, char const * const label) : - Execution_context(pt ? pt->priority() : Priority::MAX), + Execution_context(priority), Thread_cpu_support(this), - _platform_thread(pt), _state(AWAITS_START), _pd(0), _utcb_phys(0), - _signal_receiver(0) + _signal_receiver(0), + _label(label) { } @@ -270,16 +269,6 @@ void Thread::proceed() } -char const * Kernel::Thread::label() const -{ - if (!platform_thread()) { - if (!_utcb_phys) { return "idle"; } - return "core"; - } - return platform_thread()->name(); -} - - char const * Kernel::Thread::pd_label() const { if (_core()) { return "core"; } @@ -335,18 +324,17 @@ void Thread::_call_kill_pd() void Thread::_call_new_thread() { /* check permissions */ - assert(_core()); - - /* dispatch arguments */ - Call_arg const arg1 = user_arg_1(); - Call_arg const arg2 = user_arg_2(); - - /* create thread */ - Thread * const t = new ((void *)arg1) - Thread((Platform_thread *)arg2); - - /* return thread ID */ - user_arg_0((Call_ret)t->id()); + if (!_core()) { + PERR("not entitled to create thread"); + user_arg_0(0); + return; + } + /* create new thread */ + void * const p = (void *)user_arg_1(); + unsigned const priority = user_arg_2(); + char const * const label = (char *)user_arg_3(); + Thread * const t = new (p) Thread(priority, label); + user_arg_0(t->id()); } diff --git a/base-hw/src/core/kernel/thread.h b/base-hw/src/core/kernel/thread.h index cba33bbf95..40b1759133 100644 --- a/base-hw/src/core/kernel/thread.h +++ b/base-hw/src/core/kernel/thread.h @@ -22,11 +22,6 @@ #include #include -namespace Genode -{ - class Platform_thread; -} - namespace Kernel { class Thread; @@ -78,11 +73,11 @@ class Kernel::Thread STOPPED = 8, }; - Platform_thread * const _platform_thread; - State _state; - Pd * _pd; - Native_utcb * _utcb_phys; - Signal_receiver * _signal_receiver; + State _state; + Pd * _pd; + Native_utcb * _utcb_phys; + Signal_receiver * _signal_receiver; + char const * const _label; /** * Notice that another thread yielded the CPU to this thread @@ -255,9 +250,10 @@ class Kernel::Thread /** * Constructor * - * \param platform_thread corresponding userland object + * \param priority scheduling priority + * \param label debugging label */ - Thread(Platform_thread * const platform_thread); + Thread(unsigned const priority, char const * const label); /** * Prepare thread to get scheduled the first time @@ -283,11 +279,10 @@ class Kernel::Thread ** Accessors ** ***************/ - Platform_thread * platform_thread() const { return _platform_thread; } - unsigned id() const { return Object::id(); } - char const * label() const; - unsigned pd_id() const; - char const * pd_label() const; + unsigned id() const { return Object::id(); } + char const * label() const { return _label; }; + unsigned pd_id() const; + char const * pd_label() const; }; #endif /* _KERNEL__THREAD_H_ */ diff --git a/base-hw/src/core/platform_thread.cc b/base-hw/src/core/platform_thread.cc index 0e7747d493..b859da6e2f 100644 --- a/base-hw/src/core/platform_thread.cc +++ b/base-hw/src/core/platform_thread.cc @@ -28,7 +28,7 @@ bool Platform_thread::_attaches_utcb_by_itself() * virtual context area by itself, as it is done for other threads * through a sub RM-session. */ - return _pd_id == Kernel::core_id() || !main_thread(); + return _pd_id == Kernel::core_id() || !_main_thread; } @@ -46,13 +46,13 @@ Platform_thread::~Platform_thread() /* the RM client may be destructed before platform thread */ if (_rm_client) { Rm_session_component * const rm = _rm_client->member_rm_session(); - rm->detach(utcb_virt()); + rm->detach(_utcb_virt); } } /* free UTCB */ if (_pd_id == Kernel::core_id()) { Range_allocator * const ram = platform()->ram_alloc(); - ram->free(utcb_phys(), sizeof(Native_utcb)); + ram->free(_utcb_phys, sizeof(Native_utcb)); } else { Ram_session_component * const ram = dynamic_cast(core_env()->ram_session()); @@ -72,16 +72,19 @@ Platform_thread::~Platform_thread() Kernel::delete_thread(_id); } -Platform_thread::Platform_thread(const char * name, + +Platform_thread::Platform_thread(const char * const label, Thread_base * const thread_base, size_t const stack_size, unsigned const pd_id) : - _thread_base(thread_base), _stack_size(stack_size), - _pd_id(pd_id), _rm_client(0), _utcb_virt(0), - _priority(Kernel::Priority::MAX), + _thread_base(thread_base), + _stack_size(stack_size), + _pd_id(pd_id), + _rm_client(0), + _utcb_virt(0), _main_thread(0) { - strncpy(_name, name, NAME_MAX_LEN); + strncpy(_label, label, LABEL_MAX_LEN); /* create UTCB for a core thread */ Range_allocator * const ram = platform()->ram_alloc(); @@ -93,20 +96,27 @@ Platform_thread::Platform_thread(const char * name, } _utcb_virt = _utcb_phys; - /* common constructor parts */ - _init(); + /* create kernel object */ + _id = Kernel::new_thread(_kernel_thread, Kernel::Priority::MAX, _label); + if (!_id) { + PERR("failed to create kernel object"); + throw Cpu_session::Thread_creation_failed(); + } } -Platform_thread::Platform_thread(const char * name, unsigned int priority, - addr_t utcb) +Platform_thread::Platform_thread(const char * const label, + unsigned const priority, + addr_t const utcb) : - _thread_base(0), _stack_size(0), _pd_id(0), _rm_client(0), + _thread_base(0), + _stack_size(0), + _pd_id(0), + _rm_client(0), _utcb_virt((Native_utcb *)utcb), - _priority(Cpu_session::scale_priority(Kernel::Priority::MAX, priority)), _main_thread(0) { - strncpy(_name, name, NAME_MAX_LEN); + strncpy(_label, label, LABEL_MAX_LEN); /* * Allocate UTCB backing store for a thread outside of core. Page alignment @@ -123,22 +133,26 @@ Platform_thread::Platform_thread(const char * name, unsigned int priority, } _utcb_phys = (Native_utcb *)ram->phys_addr(_utcb); - /* common constructor parts */ - _init(); + /* create kernel object */ + _id = Kernel::new_thread(_kernel_thread, priority, _label); + if (!_id) { + PERR("failed to create kernel object"); + throw Cpu_session::Thread_creation_failed(); + } } int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread, Weak_ptr address_space) { - /* check if we're already in another PD */ + /* check if thread is already in another protection domain */ if (_pd_id && _pd_id != pd_id) { - PERR("already joined a PD"); + PERR("thread already in another protection domain"); return -1; } - /* denote configuration for start method */ - _pd_id = pd_id; - _main_thread = main_thread; + /* join protection domain */ + _pd_id = pd_id; + _main_thread = main_thread; _address_space = address_space; return 0; } @@ -146,12 +160,6 @@ int Platform_thread::join_pd(unsigned const pd_id, bool const main_thread, void Platform_thread::_init() { - /* create kernel object */ - _id = Kernel::new_thread(_kernel_thread, this); - if (!_id) { - PERR("failed to create kernel object"); - throw Cpu_session::Thread_creation_failed(); - } } @@ -186,14 +194,14 @@ int Platform_thread::start(void * const ip, void * const sp, write_regs[1] = Reg_id::SP; addr_t write_values[] = { (addr_t)ip, - main_thread() ? (addr_t)_utcb_virt : (addr_t)sp + _main_thread ? (addr_t)_utcb_virt : (addr_t)sp }; if (Kernel::access_thread_regs(id(), 0, WRITES, 0, write_values)) { PERR("failed to initialize thread registers"); return -1; } /* let thread participate in CPU scheduling */ - _tlb = Kernel::start_thread(id(), cpu_id, _pd_id, utcb_phys()); + _tlb = Kernel::start_thread(id(), cpu_id, _pd_id, _utcb_phys); if (!_tlb) { PERR("failed to start thread"); return -1;