From 98def2488ade1773bed6112332a014ee71fd0e97 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Tue, 28 Apr 2015 17:42:07 +0200 Subject: [PATCH] thread: move Thread_base::myself() to separate file The thread library (thread.cc) in base-foc shared 95% of the code with the generic implementation except myself(). Therefore, its implementation is now separated from the other generic sources into myself.cc, which allows base-foc to use a foc-specific primitive to enable our base libraries in L4Linux. Issue #1491 --- repos/base-codezero/lib/mk/base-common.mk | 2 +- repos/base-fiasco/lib/mk/base-common.mk | 1 + repos/base-foc/lib/mk/base-common.inc | 1 + repos/base-foc/src/base/thread/myself.cc | 24 +++ repos/base-foc/src/base/thread/thread.cc | 211 --------------------- repos/base-hw/lib/mk/base-common.inc | 2 + repos/base-hw/lib/mk/base.mk | 1 - repos/base-hw/lib/mk/core.inc | 2 - repos/base-linux/lib/mk/base.mk | 6 +- repos/base-linux/src/core/target.mk | 3 +- repos/base-nova/lib/mk/base-common.inc | 1 + repos/base-okl4/lib/mk/base-common.mk | 1 + repos/base-pistachio/lib/mk/base-common.mk | 1 + repos/base/src/base/thread/myself.cc | 34 ++++ repos/base/src/base/thread/thread.cc | 30 +-- 15 files changed, 76 insertions(+), 244 deletions(-) create mode 100644 repos/base-foc/src/base/thread/myself.cc delete mode 100644 repos/base-foc/src/base/thread/thread.cc create mode 100644 repos/base/src/base/thread/myself.cc diff --git a/repos/base-codezero/lib/mk/base-common.mk b/repos/base-codezero/lib/mk/base-common.mk index 2e200fe3d..6ebb1c13b 100644 --- a/repos/base-codezero/lib/mk/base-common.mk +++ b/repos/base-codezero/lib/mk/base-common.mk @@ -20,7 +20,7 @@ SRC_CC += elf/elf_binary.cc SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc -SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc +SRC_CC += thread/thread.cc thread/myself.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/context_allocator.cc env/utcb.cc SRC_CC += lock/cmpxchg.cc diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk index 1380eecfe..90e493920 100644 --- a/repos/base-fiasco/lib/mk/base-common.mk +++ b/repos/base-fiasco/lib/mk/base-common.mk @@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc +SRC_CC += thread/myself.cc SRC_CC += thread/context_allocator.cc INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base-foc/lib/mk/base-common.inc b/repos/base-foc/lib/mk/base-common.inc index bd17c24bd..7af66d7ff 100644 --- a/repos/base-foc/lib/mk/base-common.inc +++ b/repos/base-foc/lib/mk/base-common.inc @@ -21,6 +21,7 @@ SRC_CC += env/spin_lock.cc env/cap_map.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc +SRC_CC += thread/myself.cc SRC_CC += thread/context_allocator.cc INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base-foc/src/base/thread/myself.cc b/repos/base-foc/src/base/thread/myself.cc new file mode 100644 index 000000000..4e34a5e84 --- /dev/null +++ b/repos/base-foc/src/base/thread/myself.cc @@ -0,0 +1,24 @@ +/* + * \brief Implementation of the Thread API (foc-specific myself()) + * \author Norman Feske + * \date 2015-04-28 + */ + +/* + * Copyright (C) 2015 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 + + +Genode::Thread_base *Genode::Thread_base::myself() +{ + using namespace Fiasco; + + return reinterpret_cast(l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ]); +} + + diff --git a/repos/base-foc/src/base/thread/thread.cc b/repos/base-foc/src/base/thread/thread.cc deleted file mode 100644 index 143ce477b..000000000 --- a/repos/base-foc/src/base/thread/thread.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * \brief Implementation of the Thread API - * \author Norman Feske - * \date 2010-01-11 - */ - -/* - * Copyright (C) 2010-2013 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 -#include -#include -#include -#include - -using namespace Genode; - - -/** - * Return the managed dataspace holding the thread context area - * - * This function is provided by the process environment. - */ -namespace Genode { - Rm_session *env_context_area_rm_session(); - Ram_session *env_context_area_ram_session(); -} - - -void Thread_base::Context::stack_size(size_t const size) -{ - /* check if the stack needs to be enhanced */ - size_t const stack_size = (addr_t)_stack - stack_base; - if (stack_size >= size) { return; } - - /* check if the stack enhancement fits the context region */ - enum { - CONTEXT_SIZE = Native_config::context_virtual_size(), - CONTEXT_AREA_BASE = Native_config::context_area_virtual_base(), - UTCB_SIZE = sizeof(Native_utcb), - PAGE_SIZE_LOG2 = 12, - PAGE_SIZE = (1UL << PAGE_SIZE_LOG2), - }; - addr_t const context_base = Context_allocator::addr_to_base(this); - size_t const ds_size = align_addr(size - stack_size, PAGE_SIZE_LOG2); - if (stack_base - ds_size < context_base) { throw Stack_too_large(); } - - /* allocate and attach backing store for the stack enhancement */ - addr_t const ds_addr = stack_base - ds_size - CONTEXT_AREA_BASE; - try { - Ram_session * const ram = env_context_area_ram_session(); - Ram_dataspace_capability const ds_cap = ram->alloc(ds_size); - Rm_session * const rm = env_context_area_rm_session(); - void * const attach_addr = rm->attach_at(ds_cap, ds_addr, ds_size); - if (ds_addr != (addr_t)attach_addr) { throw Stack_alloc_failed(); } - } - catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); } - - /* update context information */ - stack_base -= ds_size; -} - - -Thread_base::Context * -Thread_base::_alloc_context(size_t stack_size, bool main_thread) -{ - /* - * Synchronize context list when creating new threads from multiple threads - * - * XXX: remove interim fix - */ - static Lock alloc_lock; - Lock::Guard _lock_guard(alloc_lock); - - /* allocate thread context */ - Context *context = _context_allocator()->alloc(this, main_thread); - if (!context) - throw Context_alloc_failed(); - - /* determine size of dataspace to allocate for context members and stack */ - enum { PAGE_SIZE_LOG2 = 12 }; - size_t ds_size = align_addr(stack_size, PAGE_SIZE_LOG2); - - if (stack_size >= Native_config::context_virtual_size() - - sizeof(Native_utcb) - (1UL << PAGE_SIZE_LOG2)) - throw Stack_too_large(); - - /* - * Calculate base address of the stack - * - * The stack is always located at the top of the context. - */ - addr_t ds_addr = Context_allocator::addr_to_base(context) + - Native_config::context_virtual_size() - - ds_size; - - /* add padding for UTCB if defined for the platform */ - if (sizeof(Native_utcb) >= (1 << PAGE_SIZE_LOG2)) - ds_addr -= sizeof(Native_utcb); - - /* allocate and attach backing store for the stack */ - Ram_dataspace_capability ds_cap; - try { - ds_cap = env_context_area_ram_session()->alloc(ds_size); - addr_t attach_addr = ds_addr - Native_config::context_area_virtual_base(); - if (attach_addr != (addr_t)env_context_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size)) - throw Stack_alloc_failed(); - } - catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); } - - /* - * Now the thread context is backed by memory, so it is safe to access its - * members. - * - * We need to initialize the context object's memory with zeroes, - * otherwise the ds_cap isn't invalid. That would cause trouble - * when the assignment operator of Native_capability is used. - */ - memset(context, 0, sizeof(Context) - sizeof(Context::utcb)); - context->thread_base = this; - context->stack_base = ds_addr; - context->ds_cap = ds_cap; - - /* - * The value at the top of the stack might get interpreted as return - * address of the thread start function by GDB, so we set it to 0. - */ - *(addr_t*)context->stack_top() = 0; - - return context; -} - - -void Thread_base::_free_context(Context* context) -{ - addr_t ds_addr = context->stack_base - Native_config::context_area_virtual_base(); - Ram_dataspace_capability ds_cap = context->ds_cap; - - /* call de-constructor explicitly before memory gets detached */ - context->~Context(); - - Genode::env_context_area_rm_session()->detach((void *)ds_addr); - Genode::env_context_area_ram_session()->free(ds_cap); - - /* context area ready for reuse */ - _context_allocator()->free(context); -} - - -void Thread_base::name(char *dst, size_t dst_len) -{ - snprintf(dst, min(dst_len, (size_t)Context::NAME_LEN), "%s", _context->name); -} - - -Thread_base *Thread_base::myself() -{ - using namespace Fiasco; - - return reinterpret_cast(l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ]); -} - - -void Thread_base::join() -{ - _join_lock.lock(); -} - - -void* Thread_base::alloc_secondary_stack(char const *name, size_t stack_size) -{ - Context *context = _alloc_context(stack_size, false); - strncpy(context->name, name, sizeof(context->name)); - return (void *)context->stack_top(); -} - - -void Thread_base::free_secondary_stack(void* stack_addr) -{ - addr_t base = Context_allocator::addr_to_base(stack_addr); - _free_context(Context_allocator::base_to_context(base)); -} - - -Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type const type, Cpu_session *cpu_session) -: - _cpu_session(cpu_session), - _context(type == REINITIALIZED_MAIN ? - _context : _alloc_context(stack_size, type == MAIN)), - _join_lock(Lock::LOCKED) -{ - strncpy(_context->name, name, sizeof(_context->name)); - _init_platform_thread(weight, type); -} - - -Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, - Type type) -: Thread_base(weight, name, stack_size, type, nullptr) { } - - -Thread_base::~Thread_base() -{ - _deinit_platform_thread(); - _free_context(_context); -} diff --git a/repos/base-hw/lib/mk/base-common.inc b/repos/base-hw/lib/mk/base-common.inc index 1616aa9de..e267eabfe 100644 --- a/repos/base-hw/lib/mk/base-common.inc +++ b/repos/base-hw/lib/mk/base-common.inc @@ -24,6 +24,8 @@ SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc SRC_CC += server/common.cc +SRC_CC += thread/thread.cc +SRC_CC += thread/myself.cc SRC_CC += thread/bootstrap.cc SRC_CC += thread/trace.cc SRC_CC += thread/context_allocator.cc diff --git a/repos/base-hw/lib/mk/base.mk b/repos/base-hw/lib/mk/base.mk index a1ac85df7..7fc562249 100644 --- a/repos/base-hw/lib/mk/base.mk +++ b/repos/base-hw/lib/mk/base.mk @@ -13,7 +13,6 @@ SRC_CC += cpu/cache.cc SRC_CC += env/env.cc SRC_CC += env/context_area.cc SRC_CC += env/reinitialize.cc -SRC_CC += thread/thread.cc SRC_CC += thread/start.cc SRC_CC += irq/platform.cc diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index 669b3e65c..9aaf06bd2 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -41,7 +41,6 @@ SRC_CC += rm_session_component.cc SRC_CC += rom_session_component.cc SRC_CC += signal_session_component.cc SRC_CC += trace_session_component.cc -SRC_CC += thread/thread.cc SRC_CC += thread_start.cc SRC_CC += rm_session_support.cc SRC_CC += pager.cc @@ -74,4 +73,3 @@ vpath boot_modules.s $(BOOT_MODULES_VPATH) vpath % $(REP_DIR)/src/core vpath % $(BASE_DIR)/src/core vpath % $(BASE_DIR)/src/platform -vpath % $(BASE_DIR)/src/base diff --git a/repos/base-linux/lib/mk/base.mk b/repos/base-linux/lib/mk/base.mk index 518701d20..e5df32113 100644 --- a/repos/base-linux/lib/mk/base.mk +++ b/repos/base-linux/lib/mk/base.mk @@ -5,10 +5,10 @@ # LIBS += startup cxx -SRC_CC += thread.cc thread_linux.cc +SRC_CC += thread/thread.cc thread/myself.cc thread/thread_linux.cc -vpath %.cc $(REP_DIR)/src/base/thread -vpath %.cc $(BASE_DIR)/src/base/thread +vpath %.cc $(REP_DIR)/src/base +vpath %.cc $(BASE_DIR)/src/base include $(REP_DIR)/lib/mk/base.inc diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 05e5afb01..4b1462716 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -23,7 +23,7 @@ SRC_CC = main.cc \ thread_linux.cc \ context_area.cc \ core_printf.cc \ - thread.cc + thread.cc myself.cc INC_DIR += $(REP_DIR)/src/core/include \ $(GEN_CORE_DIR)/include \ @@ -58,5 +58,6 @@ vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console vpath thread.cc $(BASE_DIR)/src/base/thread +vpath myself.cc $(BASE_DIR)/src/base/thread vpath trace.cc $(BASE_DIR)/src/base/thread vpath %.cc $(PRG_DIR) diff --git a/repos/base-nova/lib/mk/base-common.inc b/repos/base-nova/lib/mk/base-common.inc index 9b14e2e2a..c7309a228 100644 --- a/repos/base-nova/lib/mk/base-common.inc +++ b/repos/base-nova/lib/mk/base-common.inc @@ -19,6 +19,7 @@ SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc SRC_CC += thread/thread.cc thread/thread_context.cc thread/trace.cc +SRC_CC += thread/myself.cc SRC_CC += thread/context_allocator.cc env/cap_map.cc INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base-okl4/lib/mk/base-common.mk b/repos/base-okl4/lib/mk/base-common.mk index 05974f5fb..8f8ab959f 100644 --- a/repos/base-okl4/lib/mk/base-common.mk +++ b/repos/base-okl4/lib/mk/base-common.mk @@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc +SRC_CC += thread/myself.cc SRC_CC += thread/context_allocator.cc INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk index a98ca4a7d..c2567c91a 100644 --- a/repos/base-pistachio/lib/mk/base-common.mk +++ b/repos/base-pistachio/lib/mk/base-common.mk @@ -21,6 +21,7 @@ SRC_CC += lock/lock.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += server/server.cc server/common.cc SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc +SRC_CC += thread/myself.cc SRC_CC += thread/context_allocator.cc INC_DIR += $(REP_DIR)/src/base/lock diff --git a/repos/base/src/base/thread/myself.cc b/repos/base/src/base/thread/myself.cc new file mode 100644 index 000000000..e731d8702 --- /dev/null +++ b/repos/base/src/base/thread/myself.cc @@ -0,0 +1,34 @@ +/* + * \brief Implementation of the Thread API (generic myself()) + * \author Norman Feske + * \date 2015-04-28 + */ + +/* + * Copyright (C) 2015 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 + + +Genode::Thread_base *Genode::Thread_base::myself() +{ + int dummy = 0; /* used for determining the stack pointer */ + + /* + * If the stack pointer is outside the thread-context area, we assume that + * we are the main thread because this condition can never met by any other + * thread. + */ + addr_t sp = (addr_t)(&dummy); + if (sp < Native_config::context_area_virtual_base() || + sp >= Native_config::context_area_virtual_base() + + Native_config::context_area_virtual_size()) + return 0; + + addr_t base = Context_allocator::addr_to_base(&dummy); + return Context_allocator::base_to_context(base)->thread_base; +} diff --git a/repos/base/src/base/thread/thread.cc b/repos/base/src/base/thread/thread.cc index 0899bf9b6..ecd0e6f5f 100644 --- a/repos/base/src/base/thread/thread.cc +++ b/repos/base/src/base/thread/thread.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2010-2015 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. @@ -153,26 +153,6 @@ void Thread_base::name(char *dst, size_t dst_len) } -Thread_base *Thread_base::myself() -{ - int dummy = 0; /* used for determining the stack pointer */ - - /* - * If the stack pointer is outside the thread-context area, we assume that - * we are the main thread because this condition can never met by any other - * thread. - */ - addr_t sp = (addr_t)(&dummy); - if (sp < Native_config::context_area_virtual_base() || - sp >= Native_config::context_area_virtual_base() + - Native_config::context_area_virtual_size()) - return 0; - - addr_t base = Context_allocator::addr_to_base(&dummy); - return Context_allocator::base_to_context(base)->thread_base; -} - - void Thread_base::join() { _join_lock.lock(); } @@ -191,7 +171,7 @@ void Thread_base::free_secondary_stack(void* stack_addr) } -Thread_base::Thread_base(size_t quota, const char *name, size_t stack_size, +Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, Type type, Cpu_session *cpu_session) : _cpu_session(cpu_session), @@ -200,13 +180,13 @@ Thread_base::Thread_base(size_t quota, const char *name, size_t stack_size, _join_lock(Lock::LOCKED) { strncpy(_context->name, name, sizeof(_context->name)); - _init_platform_thread(quota, type); + _init_platform_thread(weight, type); } -Thread_base::Thread_base(size_t quota, const char *name, size_t stack_size, +Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size, Type type) -: Thread_base(quota, name, stack_size, type, nullptr) { } +: Thread_base(weight, name, stack_size, type, nullptr) { } Thread_base::~Thread_base()