mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-04 02:01:53 +00:00
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
This commit is contained in:
parent
55c0a947e4
commit
98def2488a
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
24
repos/base-foc/src/base/thread/myself.cc
Normal file
24
repos/base-foc/src/base/thread/myself.cc
Normal file
@ -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 <base/thread.h>
|
||||
|
||||
|
||||
Genode::Thread_base *Genode::Thread_base::myself()
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
return reinterpret_cast<Thread_base*>(l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ]);
|
||||
}
|
||||
|
||||
|
@ -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 <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <util/string.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
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<Thread_base*>(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);
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
34
repos/base/src/base/thread/myself.cc
Normal file
34
repos/base/src/base/thread/myself.cc
Normal file
@ -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 <base/thread.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user