base: hide internals of the Thread API

This patch moves details about the stack allocation and organization
the base-internal headers. Thereby, I replaced the notion of "thread
contexts" by "stacks" as this term is much more intuitive. The fact that
we place thread-specific information at the bottom of the stack is not
worth introducing new terminology.

Issue #1832
This commit is contained in:
Norman Feske 2016-01-23 14:42:55 +01:00 committed by Christian Helmuth
parent 3c686fc9c6
commit 7f73e5e879
115 changed files with 982 additions and 770 deletions

View File

@ -65,7 +65,7 @@ namespace Genode {
/**
* Empty UTCB type expected by the thread library
*
* On this kernel, UTCBs are not placed within the the context area. Each
* On this kernel, UTCBs are not placed within the the stack area. Each
* thread can request its own UTCB pointer using the kernel interface.
*/
typedef struct { } Native_utcb;
@ -76,17 +76,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
struct Native_pd_args { };

View File

@ -21,7 +21,7 @@ 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
SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc

View File

@ -306,8 +306,8 @@ void Platform::_setup_mem_alloc()
}
region.start = addr; region.end = addr + size;
if (!region.intersects(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size())) {
if (!region.intersects(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size())) {
add_region(region, _ram_alloc);
add_region(region, _core_address_ranges());
}
@ -411,9 +411,9 @@ void Platform::_setup_basics()
_vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start;
_region_alloc.add_range(_vm_start, _vm_size);
/* preserve context area in core's virtual address space */
_region_alloc.remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
/* preserve stack area in core's virtual address space */
_region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
/* I/O memory could be the whole user address space */
/* FIXME if the kernel helps to find out max address - use info here */

View File

@ -2,7 +2,7 @@ TARGET = core
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += context_area.cc \
SRC_CC += stack_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
@ -62,7 +62,7 @@ vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <platform.h>
#include <core_env.h>
@ -35,7 +38,7 @@ void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform()->core_mem_alloc())
Platform_thread(0, _context->name);
Platform_thread(0, _stack->name().string());
platform_specific()->core_pd()->bind_thread(_tid.pt);

View File

@ -82,9 +82,29 @@ namespace Fiasco {
namespace Genode {
typedef Fiasco::l4_cap_idx_t Native_thread_id;
typedef Fiasco::l4_cap_idx_t Native_thread;
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;
typedef Fiasco::l4_utcb_t* Native_utcb;
struct Native_utcb
{
/*
* The 'Native_utcb' is located within the stack slot of the thread.
* We merely use it for remembering a pointer to the real UTCB, which
* resides somewhere in the kernel's address space.
*/
Fiasco::l4_utcb_t *foc_utcb = nullptr;
};
/**

View File

@ -24,9 +24,9 @@ namespace Genode {
struct Thread_state : Thread_state_base
{
Native_thread kcap; /* thread's gate cap in its pd */
Fiasco::l4_cap_idx_t kcap; /* thread's gate cap in its pd */
int id; /* id of gate capability */
Native_utcb utcb; /* thread's utcb in its pd */
addr_t utcb; /* thread's utcb in its pd */
unsigned exceptions; /* counts exceptions raised by the thread */
bool paused; /* indicates whether thread is stopped */
bool in_exception; /* true if thread is in exception */

View File

@ -53,7 +53,7 @@ namespace Genode {
_sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
Thread_base::myself()->tid());
Thread_base::myself()->tid().kcap);
if (l4_error(tag))
PERR("l4_irq_attach failed with %ld!", l4_error(tag));
}

View File

@ -1,5 +1,5 @@
/*
* \brief Platform-specific context area definitions
* \brief Platform-specific stack area definitions
* \author Stefan Kalkowski
* \date 2014-01-24
*/
@ -21,17 +21,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x20000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
}

View File

@ -1,5 +1,5 @@
/*
* \brief Platform-specific context area definitions
* \brief Platform-specific stack area definitions
* \author Stefan Kalkowski
* \date 2014-01-24
*/
@ -21,17 +21,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
}

View File

@ -21,7 +21,8 @@ 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
SRC_CC += thread/stack_allocator.cc
SRC_CC += thread/thread_utcb.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc \
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc \
env/cap_map_remove.cc env/cap_alloc.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc

View File

@ -19,6 +19,9 @@
#include <base/sleep.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
namespace Fiasco {
#include <l4/sys/utcb.h>
}
@ -30,8 +33,8 @@ void Thread_base::_deinit_platform_thread()
{
using namespace Fiasco;
if (_context->utcb && _thread_cap.valid()) {
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(_context->utcb)->user[UTCB_TCR_BADGE];
if (_tid.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);
env()->rm_session()->remove_client(_pager_cap);
@ -59,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 = Fiasco::MAIN_THREAD_CAP;
_tid.kcap = Fiasco::MAIN_THREAD_CAP;
_thread_cap = env()->parent()->main_thread_cap();
if (!_thread_cap.valid())
@ -83,15 +86,19 @@ void Thread_base::start()
Thread_state state;
try { state = _cpu_session->state(_thread_cap); }
catch (...) { throw Cpu_session::Thread_creation_failed(); }
_tid = state.kcap;
_context->utcb = state.utcb;
/* remember UTCB of the new thread */
Fiasco::l4_utcb_t * const foc_utcb = (Fiasco::l4_utcb_t *)state.utcb;
utcb()->foc_utcb = foc_utcb;
_tid = Native_thread(state.kcap);
Cap_index *i = cap_map()->insert(state.id, state.kcap);
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
/* register initial IP and SP at core */
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top());
}

View File

@ -43,7 +43,7 @@ void Genode::Cpu_session_component::enable_vcpu(Genode::Thread_capability thread
auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) return;
Native_thread tid = thread->platform_thread()->thread().local.dst();
l4_cap_idx_t tid = thread->platform_thread()->thread().local.dst();
l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state);
if (l4_msgtag_has_error(tag))
@ -103,7 +103,7 @@ void Genode::Cpu_session_component::single_step(Genode::Thread_capability thread
auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) return;
Native_thread tid = thread->platform_thread()->thread().local.dst();
Fiasco::l4_cap_idx_t tid = thread->platform_thread()->thread().local.dst();
enum { THREAD_SINGLE_STEP = 0x40000 };
int flags = enable ? THREAD_SINGLE_STEP : 0;

View File

@ -38,7 +38,7 @@ class Genode::Irq_object
Signal_context_capability _sig_cap;
Native_thread _capability() const { return _cap->kcap(); }
Fiasco::l4_cap_idx_t _capability() const { return _cap->kcap(); }
public:

View File

@ -48,8 +48,8 @@ namespace Genode {
addr_t utcb_area_start()
{
return (Native_config::context_area_virtual_base() +
THREAD_MAX * Native_config::context_virtual_size());
return (Native_config::stack_area_virtual_base() +
THREAD_MAX * Native_config::stack_virtual_size());
}
Cap_mapping _task;

View File

@ -42,7 +42,7 @@ namespace Genode {
Cap_mapping _gate;
Cap_mapping _pager;
Cap_mapping _irq;
Native_utcb _utcb;
addr_t _utcb;
char _name[32]; /* thread name that will be
registered at the kernel
debugger */
@ -185,7 +185,7 @@ namespace Genode {
Cap_mapping& gate() { return _gate; }
const char *name() const { return _name; }
bool core_thread() const { return _core_thread; }
Native_utcb utcb() const { return _utcb; }
addr_t utcb() const { return _utcb; }
};
}

View File

@ -106,7 +106,7 @@ void Ipc_pager::reply_and_wait_for_fault()
}
l4_utcb_mr()->mr[1] = _reply_mapping.fpage().raw;
_tag = l4_ipc_send_and_wait(_last, l4_utcb(), snd_tag,
_tag = l4_ipc_send_and_wait(_last.kcap, l4_utcb(), snd_tag,
&label, L4_IPC_SEND_TIMEOUT_0);
int err = l4_ipc_error(_tag, l4_utcb());
if (err) {
@ -119,7 +119,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup()
{
l4_cap_idx_t dst = Fiasco::Capability::valid(_last) ? _last : L4_SYSF_REPLY;
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap) ? _last.kcap : L4_SYSF_REPLY;
/* answer wakeup call from one of core's region-manager sessions */
l4_ipc_send(dst, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_SEND_TIMEOUT_0);
@ -129,7 +129,7 @@ void Ipc_pager::acknowledge_wakeup()
void Ipc_pager::acknowledge_exception()
{
memcpy(l4_utcb_exc(), &_regs, sizeof(l4_exc_regs_t));
l4_cap_idx_t dst = Fiasco::Capability::valid(_last) ? _last : L4_SYSF_REPLY;
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap) ? _last.kcap : L4_SYSF_REPLY;
l4_ipc_send(dst, l4_utcb(), l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0), L4_IPC_SEND_TIMEOUT_0);
}

View File

@ -53,7 +53,7 @@ class Genode::Interrupt_handler : public Thread<2048*sizeof(long)>
void entry();
static Native_thread handler_cap()
static Fiasco::l4_cap_idx_t handler_cap()
{
static Interrupt_handler handler;
return handler._thread_cap.dst();

View File

@ -69,7 +69,7 @@ void Pager_entrypoint::entry()
PDBG("Could not resolve pf=%p ip=%p",
(void*)_pager.fault_addr(), (void*)_pager.fault_ip());
} else {
_pager.set_reply_dst(obj->badge());
_pager.set_reply_dst(Native_thread(obj->badge()));
reply_pending = true;
return;
}
@ -99,7 +99,7 @@ void Pager_entrypoint::entry()
}
/* send wake up message to requested thread */
_pager.set_reply_dst(obj->badge());
_pager.set_reply_dst(Native_thread(obj->badge()));
_pager.acknowledge_exception();
break;
}
@ -121,7 +121,7 @@ void Pager_entrypoint::entry()
* that case we unblock it immediately.
*/
if (!obj->state.paused) {
_pager.set_reply_dst(obj->badge());
_pager.set_reply_dst(Native_thread(obj->badge()));
reply_pending = true;
}
break;

View File

@ -327,8 +327,8 @@ void Platform::_setup_mem_alloc()
}
region.start = addr; region.end = addr + size;
if (!region.intersects(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size())) {
if (!region.intersects(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size())) {
add_region(region, _ram_alloc);
add_region(region, _core_address_ranges());
}
@ -402,9 +402,9 @@ void Platform::_setup_basics()
_vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start;
_region_alloc.add_range(_vm_start, _vm_size);
/* preserve context area in core's virtual address space */
_region_alloc.remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
/* preserve stack area in core's virtual address space */
_region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
/* preserve utcb- area in core's virtual address space */
_region_alloc.remove_range((addr_t)l4_utcb(), L4_PAGESIZE * 16);

View File

@ -54,16 +54,19 @@ int Platform_pd::bind_thread(Platform_thread *thread)
if (_threads[i])
continue;
_threads[i] = thread;
_threads[i] = thread;
if (thread->core_thread())
thread->_utcb = (l4_utcb_t*) (core_utcb_base() + i * L4_UTCB_OFFSET);
thread->_utcb = (addr_t) (core_utcb_base() + i * L4_UTCB_OFFSET);
else
thread->_utcb =
reinterpret_cast<l4_utcb_t*>(utcb_area_start() + i * L4_UTCB_OFFSET);
Native_thread cap_offset = THREAD_AREA_BASE + i * THREAD_AREA_SLOT;
thread->_gate.remote = cap_offset + THREAD_GATE_CAP;
thread->_pager.remote = cap_offset + THREAD_PAGER_CAP;
thread->_irq.remote = cap_offset + THREAD_IRQ_CAP;
reinterpret_cast<addr_t>(utcb_area_start() + i * L4_UTCB_OFFSET);
Fiasco::l4_cap_idx_t cap_offset = THREAD_AREA_BASE + i * THREAD_AREA_SLOT;
thread->_gate.remote = cap_offset + THREAD_GATE_CAP;
thread->_pager.remote = cap_offset + THREAD_PAGER_CAP;
thread->_irq.remote = cap_offset + THREAD_IRQ_CAP;
/* if it's no core-thread we have to map parent and pager gate cap */
if (!thread->core_thread()) {

View File

@ -45,7 +45,7 @@ int Platform_thread::start(void *ip, void *sp)
l4_thread_control_start();
l4_thread_control_pager(_pager.remote);
l4_thread_control_exc_handler(_pager.remote);
l4_thread_control_bind(_utcb, _platform_pd->native_task().dst());
l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().dst());
l4_msgtag_t tag = l4_thread_control_commit(_thread.local.dst());
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_control_commit for %lx failed!",

View File

@ -5,7 +5,7 @@ GEN_CORE_DIR = $(BASE_DIR)/src/core
LIBS += base-common
SRC_CC += context_area.cc \
SRC_CC += stack_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
@ -45,7 +45,7 @@ INC_DIR += $(REP_DIR)/src/core/include \
include $(GEN_CORE_DIR)/version.inc
vpath context_area.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath cpu_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)

View File

@ -16,6 +16,9 @@
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <platform.h>
#include <core_env.h>
@ -43,19 +46,24 @@ void Thread_base::start()
/* create and start platform thread */
Platform_thread *pt =
new(platform()->core_mem_alloc()) Platform_thread(_context->name);
new(platform()->core_mem_alloc()) Platform_thread(_stack->name().string());
if (platform_specific()->core_pd()->bind_thread(pt))
throw Cpu_session::Thread_creation_failed();
_tid = pt->gate().remote;
l4_utcb_t *foc_utcb = (l4_utcb_t *)(pt->utcb());
_tid = Native_thread(pt->gate().remote);
utcb()->foc_utcb = foc_utcb;
_thread_cap =
reinterpret_cap_cast<Cpu_thread>(Native_capability(pt->thread().local));
pt->pager(platform_specific()->core_pager());
_context->utcb = pt->utcb();
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx();
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx();
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
pt->start((void *)_thread_start, stack_top());
}

View File

@ -48,7 +48,7 @@ static inline void thread_yield() { Fiasco::l4_thread_yield(); }
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{
Genode::Native_thread_id tid = thread_base ?
thread_base->tid() :
thread_base->tid().kcap :
Fiasco::MAIN_THREAD_CAP;
Genode::Native_thread_id irq = tid + Fiasco::THREAD_IRQ_CAP;
Fiasco::l4_irq_trigger(irq);
@ -62,7 +62,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
static inline void thread_switch_to(Genode::Thread_base *thread_base)
{
Genode::Native_thread_id tid = thread_base ?
thread_base->tid() :
thread_base->tid().kcap :
Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_thread_switch(tid);
}
@ -82,7 +82,7 @@ static void thread_stop_myself()
Genode::Thread_base *myself = Genode::Thread_base::myself();
Genode::Native_thread_id tid = myself ?
myself->tid() :
myself->tid().kcap :
Fiasco::MAIN_THREAD_CAP;
Genode::Native_thread_id irq = tid + THREAD_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_NEVER);

View File

@ -19,6 +19,7 @@
#include <kernel/log.h>
#include <base/native_capability.h>
#include <base/ipc_msgbuf.h>
#include <base/printf.h>
namespace Genode
{
@ -80,17 +81,17 @@ struct Genode::Native_region
struct Genode::Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0xe0000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
@ -105,8 +106,8 @@ class Genode::Native_utcb
private:
Kernel::capid_t _caps[MAX_CAP_ARGS]; /* capability buffer */
size_t _cap_cnt = 0; /* capability counter */
size_t _size = 0; /* bytes to transfer */
size_t _cap_cnt; /* capability counter */
size_t _size; /* bytes to transfer */
uint8_t _buf[get_page_size() - sizeof(_caps) -
sizeof(_cap_cnt) - sizeof(_size)];
@ -190,7 +191,7 @@ namespace Genode
/**
* The main thread's UTCB, used during bootstrap of the main thread before it
* allocates its context area, needs to be outside the virtual memory area
* allocates its stack area, needs to be outside the virtual memory area
* controlled by the RM session, because it is needed before the main
* thread can access its RM session.
*/

View File

@ -25,7 +25,7 @@ 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
SRC_CC += thread/stack_allocator.cc
SRC_CC += kernel/interface.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -9,7 +9,7 @@ LIBS += base-common startup
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc
SRC_CC += env/context_area.cc
SRC_CC += env/stack_area.cc
SRC_CC += env/reinitialize.cc
SRC_CC += thread/start.cc
SRC_CC += irq/platform.cc

View File

@ -33,7 +33,7 @@ SRC_CC += pd_assign_pci.cc
SRC_CC += platform.cc
SRC_CC += platform_pd.cc
SRC_CC += platform_thread.cc
SRC_CC += context_area.cc
SRC_CC += stack_area.cc
SRC_CC += ram_session_component.cc
SRC_CC += ram_session_support.cc
SRC_CC += rm_session_component.cc

View File

@ -17,6 +17,9 @@
#include <base/env.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* base-hw includes */
#include <kernel/interface.h>
@ -57,9 +60,9 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
** Thread_base **
*****************/
Native_utcb * Thread_base::utcb()
Native_utcb *Thread_base::utcb()
{
if (this) { return &_context->utcb; }
if (this) { return &_stack->utcb(); }
return utcb_main_thread();
}

View File

@ -18,9 +18,12 @@
#include <base/sleep.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/stack_allocator.h>
using namespace Genode;
namespace Genode { Rm_session * env_context_area_rm_session(); }
namespace Genode { Rm_session * env_stack_area_rm_session(); }
namespace Hw {
extern Ram_dataspace_capability _main_thread_utcb_ds;
@ -39,18 +42,19 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
/* create server object */
char buf[48];
name(buf, sizeof(buf));
addr_t const utcb = (addr_t)&_context->utcb;
addr_t const utcb = (addr_t)&_stack->utcb();
_thread_cap = _cpu_session->create_thread(weight, buf, utcb);
return;
}
/* if we got reinitialized we have to get rid of the old UTCB */
size_t const utcb_size = sizeof(Native_utcb);
addr_t const context_area = Native_config::context_area_virtual_base();
addr_t const utcb_new = (addr_t)&_context->utcb - context_area;
Rm_session * const rm = env_context_area_rm_session();
size_t const utcb_size = sizeof(Native_utcb);
addr_t const stack_area = Native_config::stack_area_virtual_base();
addr_t const utcb_new = (addr_t)&_stack->utcb() - stack_area;
Rm_session * const rm = env_stack_area_rm_session();
if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); }
/* remap initial main-thread UTCB according to context-area spec */
/* remap initial main-thread UTCB according to stack-area spec */
try { rm->attach_at(Hw::_main_thread_utcb_ds, utcb_new, utcb_size); }
catch(...) {
PERR("failed to re-map UTCB");
@ -69,12 +73,12 @@ void Thread_base::_deinit_platform_thread()
_cpu_session->kill_thread(_thread_cap);
/* detach userland thread-context */
size_t const size = sizeof(_context->utcb);
addr_t utcb = Context_allocator::addr_to_base(_context) +
Native_config::context_virtual_size() - size -
Native_config::context_area_virtual_base();
env_context_area_rm_session()->detach(utcb);
/* detach userland stack */
size_t const size = sizeof(_stack->utcb());
addr_t utcb = Stack_allocator::addr_to_base(_stack) +
Native_config::stack_virtual_size() - size -
Native_config::stack_area_virtual_base();
env_stack_area_rm_session()->detach(utcb);
if (_pager_cap.valid()) {
env()->rm_session()->remove_client(_pager_cap);
@ -91,20 +95,20 @@ void Thread_base::start()
_pager_cap = env()->rm_session()->add_client(_thread_cap);
_cpu_session->set_pager(_thread_cap, _pager_cap);
/* attach userland thread-context */
/* attach userland stack */
try {
Ram_dataspace_capability ds = _cpu_session->utcb(_thread_cap);
size_t const size = sizeof(_context->utcb);
addr_t dst = Context_allocator::addr_to_base(_context) +
Native_config::context_virtual_size() - size -
Native_config::context_area_virtual_base();
env_context_area_rm_session()->attach_at(ds, dst, size);
size_t const size = sizeof(_stack->utcb());
addr_t dst = Stack_allocator::addr_to_base(_stack) +
Native_config::stack_virtual_size() - size -
Native_config::stack_area_virtual_base();
env_stack_area_rm_session()->attach_at(ds, dst, size);
} catch (...) {
PERR("failed to attach userland thread-context");
PERR("failed to attach userland stack");
sleep_forever();
}
/* start thread with its initial IP and aligned SP */
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top());
}

View File

@ -95,7 +95,7 @@ namespace Genode {
* \param quota CPU quota that shall be granted to the thread
* \param label debugging label
* \param virt_prio unscaled processor-scheduling priority
* \param utcb core local pointer to userland thread-context
* \param utcb core local pointer to userland stack
*/
Platform_thread(size_t const quota, const char * const label,
unsigned const virt_prio, addr_t const utcb);

View File

@ -138,8 +138,8 @@ Platform::Platform()
/* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(
Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
_init_io_port_alloc();

View File

@ -17,6 +17,9 @@
#include <base/sleep.h>
#include <base/env.h>
/* base-internal stack */
#include <base/internal/stack.h>
/* core includes */
#include <map_local.h>
#include <kernel/kernel.h>
@ -25,11 +28,10 @@
using namespace Genode;
namespace Genode { Rm_session * env_context_area_rm_session(); }
namespace Genode { Rm_session *env_stack_area_rm_session(); }
namespace Hw { extern Untyped_capability _main_thread_cap; }
namespace Hw {
extern Untyped_capability _main_thread_cap;
}
void Thread_base::start()
{
@ -56,13 +58,13 @@ void Thread_base::_init_platform_thread(size_t, Type type)
{
if (type == NORMAL) {
_tid.platform_thread = new (platform()->core_mem_alloc())
Platform_thread(_context->name, &_context->utcb);
Platform_thread(_stack->name().string(), &_stack->utcb());
return;
}
/* remap initial main-thread UTCB according to context-area spec */
/* remap initial main-thread UTCB according to stack-area spec */
Genode::map_local((addr_t)Kernel::Core_thread::singleton().utcb(),
(addr_t)&_context->utcb,
(addr_t)&_stack->utcb(),
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
/* adjust initial object state in case of a main thread */

View File

@ -26,7 +26,7 @@
* Genode from POSIX.
*/
extern Genode::addr_t _context_area_start;
extern Genode::addr_t _stack_area_start;
namespace Genode {
@ -128,21 +128,21 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*
* Please update platform-specific files after changing these
* functions, e.g., 'base-linux/src/ld/context_area.*.ld'.
* functions, e.g., 'base-linux/src/ld/stack_area.*.ld'.
*/
static addr_t context_area_virtual_base() {
return align_addr((addr_t)&_context_area_start, 20); }
static addr_t stack_area_virtual_base() {
return align_addr((addr_t)&_stack_area_start, 20); }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
class Native_pd_args

View File

@ -19,7 +19,7 @@ SRC_CC += lock/lock.cc
SRC_CC += env/rm_session_mmap.cc env/debug.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/trace.cc thread/thread_env.cc thread/context_allocator.cc
SRC_CC += thread/trace.cc thread/thread_env.cc thread/stack_allocator.cc
SRC_CC += irq/platform.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -10,7 +10,7 @@
LIBS += base-common syscall cxx
SRC_CC += console/log_console.cc
SRC_CC += env/env.cc env/platform_env.cc env/context_area.cc
SRC_CC += env/env.cc env/platform_env.cc env/stack_area.cc
SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(REP_DIR)/src/include $(BASE_DIR)/src/include

View File

@ -4,13 +4,13 @@
#
# Startup code to be used when building a program and linker script that is
# specific for Linux. We also reserve the thread-context area via a segment in
# specific for Linux. We also reserve the stack area via a segment in
# the program under Linux to prevent clashes with vdso.
#
ifneq ($(USE_HOST_LD_SCRIPT),yes)
LD_TEXT_ADDR ?= 0x01000000
LD_SCRIPT_STATIC = $(call select_from_repositories,src/ld/genode.ld) \
$(call select_from_repositories,src/ld/context_area.nostdlib.ld)
$(call select_from_repositories,src/ld/stack_area.nostdlib.ld)
else
LD_SCRIPT_STATIC ?=
endif

View File

@ -10,7 +10,7 @@ endif
#
# We need to manually add the default linker script on the command line in case
# of standard library use. Otherwise, we were not able to extend it by the
# context area section.
# stack area section.
#
ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_STATIC = ldscripts/armelf_linux_eabi.xc

View File

@ -6,7 +6,7 @@ SPECS += linux x86_32
#
# We need to manually add the default linker script on the command line in case
# of standard library use. Otherwise, we were not able to extend it by the
# context area section.
# stack area section.
#
ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_DEFAULT = ldscripts/elf_i386.xc

View File

@ -6,7 +6,7 @@ SPECS += linux x86_64
#
# We need to manually add the default linker script on the command line in case
# of standard library use. Otherwise, we were not able to extend it by the
# context area section.
# stack area section.
#
ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_DEFAULT = ldscripts/elf_x86_64.xc

View File

@ -8,7 +8,7 @@
* dataspaces and 2) get the kernel to manage VM regions as we intent.
*
* The kernel sets up mappings for the binary on execve(), which are text and
* data segments, the context area and special regions (stack, vdso, vsyscall).
* data segments, the stack area and special regions (stack, vdso, vsyscall).
* Later mappings are done by the Genode program itself, which knows nothing
* about these initial mappings. Therefore, most mmap() operations are _soft_
* to detect region conflicts with existing mappings or let the kernel find
@ -17,10 +17,10 @@
* but not populated dataspaces are "holes" in the Linux VM space represented
* by PROT_NONE mappings (see _reserve_local()).
*
* The context area is a managed dataspace as on other platforms, which is
* The stack area is a managed dataspace as on other platforms, which is
* created and attached during program launch. The managed dataspace replaces
* the inital reserved area, which is therefore flushed beforehand. Hybrid
* programs have no context area.
* programs have no stack area.
*
* Note, we do not support nesting of managed dataspaces.
*/
@ -40,7 +40,7 @@
/* base-internal includes */
#include <base/internal/local_capability.h>
#include <base/internal/platform_env.h>
#include <base/internal/context_area.h>
#include <base/internal/stack_area.h>
using namespace Genode;
@ -58,13 +58,13 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
addr_t local_addr,
Genode::size_t size)
{
/* special handling for context area */
/* special handling for stack area */
if (use_local_addr
&& local_addr == Native_config::context_area_virtual_base()
&& size == Native_config::context_area_virtual_size()) {
&& local_addr == Native_config::stack_area_virtual_base()
&& size == Native_config::stack_area_virtual_size()) {
/*
* On the first request to reserve the context area, we flush the
* On the first request to reserve the stack area, we flush the
* initial mapping preserved in linker script and apply the actual
* reservation. Subsequent requests are just ignored.
*/
@ -73,8 +73,8 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
{
Context()
{
flush_context_area();
reserve_context_area();
flush_stack_area();
reserve_stack_area();
}
} inst;

View File

@ -19,6 +19,9 @@
#include <base/sleep.h>
#include <linux_cpu_session/linux_cpu_session.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* Linux syscall bindings */
#include <linux_syscalls.h>
@ -77,7 +80,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
/* for normal threads create an object at the CPU session */
if (type == NORMAL) {
_thread_cap = _cpu_session->create_thread(weight, _context->name);
_thread_cap = _cpu_session->create_thread(weight, _stack->name().string());
return;
}
/* adjust initial object state for main threads */

View File

@ -28,7 +28,6 @@
/* base-internal includes */
#include <base/internal/platform_env.h>
namespace Genode {
/**

View File

@ -18,29 +18,29 @@
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/context_area.h>
#include <base/internal/stack_area.h>
/**
* Region-manager session for allocating thread contexts
* Region-manager session for allocating stacks
*
* This class corresponds to the managed dataspace that is normally
* used for organizing thread contexts with the thread context area.
* It "emulates" the sub address space by adjusting the local address
* argument to 'attach' with the offset of the thread context area.
* This class corresponds to the managed dataspace that is normally used for
* organizing stacks within the stack. It "emulates" the sub address space by
* adjusting the local address argument to 'attach' with the offset of the
* stack area.
*/
class Context_area_rm_session : public Genode::Rm_session
class Stack_area_rm_session : public Genode::Rm_session
{
public:
Context_area_rm_session()
Stack_area_rm_session()
{
flush_context_area();
reserve_context_area();
flush_stack_area();
reserve_stack_area();
}
/**
* Attach backing store to thread-context area
* Attach backing store to stack area
*/
Local_addr attach(Genode::Dataspace_capability ds_cap,
Genode::size_t size, Genode::off_t offset,
@ -49,9 +49,9 @@ class Context_area_rm_session : public Genode::Rm_session
{
using namespace Genode;
/* convert context-area-relative to absolute virtual address */
/* convert stack-area-relative to absolute virtual address */
addr_t addr = local_addr;
addr += Native_config::context_area_virtual_base();
addr += Native_config::stack_area_virtual_base();
/* use anonymous mmap for allocating stack backing store */
int flags = MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE;
@ -65,7 +65,7 @@ class Context_area_rm_session : public Genode::Rm_session
}
void detach(Local_addr local_addr) {
PWRN("context area detach from 0x%p - not implemented", (void *)local_addr); }
PWRN("stack area detach from 0x%p - not implemented", (void *)local_addr); }
Genode::Pager_capability add_client(Genode::Thread_capability) {
return Genode::Pager_capability(); }
@ -81,7 +81,7 @@ class Context_area_rm_session : public Genode::Rm_session
};
class Context_area_ram_session : public Genode::Ram_session
class Stack_area_ram_session : public Genode::Ram_session
{
public:
@ -102,19 +102,19 @@ class Context_area_ram_session : public Genode::Ram_session
/**
* Return single instance of the context-area RM and RAM session
* Return single instance of the stack-area RM and RAM session
*/
namespace Genode {
Rm_session *env_context_area_rm_session()
Rm_session *env_stack_area_rm_session()
{
static Context_area_rm_session inst;
static Stack_area_rm_session inst;
return &inst;
}
Ram_session *env_context_area_ram_session()
Ram_session *env_stack_area_ram_session()
{
static Context_area_ram_session inst;
static Stack_area_ram_session inst;
return &inst;
}
}

View File

@ -24,7 +24,7 @@ SRC_CC = main.cc \
signal_source_component.cc \
trace_session_component.cc \
thread_linux.cc \
context_area.cc \
stack_area.cc \
core_printf.cc \
thread.cc myself.cc

View File

@ -211,7 +211,7 @@ namespace Genode {
* the common use case of managed dataspaces as mechanism
* to reserve parts of the local address space from being
* populated by the 'env()->rm_session()'. (i.e., for the
* context area, or for the placement of consecutive
* stack area, or for the placement of consecutive
* shared-library segments)
*/
addr_t _base;

View File

@ -1,5 +1,5 @@
/*
* \brief Linux-specific utilities for context area
* \brief Linux-specific utilities for stack area
* \author Christian Helmuth
* \date 2013-09-26
*/
@ -11,8 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__BASE__INTERNAL__CONTEXT_AREA_H_
#define _INCLUDE__BASE__INTERNAL__CONTEXT_AREA_H_
#ifndef _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
#define _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
/* Genode includes */
#include <base/thread.h>
@ -24,12 +24,12 @@
#include <sys/mman.h>
static inline void flush_context_area()
static inline void flush_stack_area()
{
using namespace Genode;
void * const base = (void *) Native_config::context_area_virtual_base();
size_t const size = Native_config::context_area_virtual_size();
void * const base = (void *) Native_config::stack_area_virtual_base();
size_t const size = Native_config::stack_area_virtual_size();
int ret;
if ((ret = lx_munmap(base, size)) < 0) {
@ -39,14 +39,14 @@ static inline void flush_context_area()
}
static inline Genode::addr_t reserve_context_area()
static inline Genode::addr_t reserve_stack_area()
{
using namespace Genode;
int const flags = MAP_ANONYMOUS | MAP_PRIVATE;
int const prot = PROT_NONE;
size_t const size = Native_config::context_area_virtual_size();
void * const addr_in = (void *)Native_config::context_area_virtual_base();
size_t const size = Native_config::stack_area_virtual_size();
void * const addr_in = (void *)Native_config::stack_area_virtual_base();
void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0);
/* reserve at local address failed - unmap incorrect mapping */
@ -61,4 +61,4 @@ static inline Genode::addr_t reserve_context_area()
return (addr_t) addr_out;
}
#endif /* _INCLUDE__BASE__INTERNAL__CONTEXT_AREA_H_ */
#endif /* _INCLUDE__BASE__INTERNAL__STACK_AREA_H_ */

View File

@ -13,16 +13,16 @@
PHDRS
{
context_area PT_LOAD FLAGS(0);
stack_area PT_LOAD FLAGS(0);
}
SECTIONS
{
. = 0x40000000;
_context_area_start = .;
_stack_area_start = .;
/*
* Since Linux loads ldso page aligned, we align the context area after
* Since Linux loads ldso page aligned, we align the stack area after
* loading to a 1 MiB boundary, therefore we reserve one MiB more here.
*/
.context_area : { . += 0x10100000; } : context_area
.stack_area : { . += 0x10100000; } : stack_area
}

View File

@ -14,6 +14,6 @@
SECTIONS
{
. = 0x40000000;
_context_area_start = .;
.context_area : { . += 0x10000000; }
_stack_area_start = .;
.stack_area : { . += 0x10000000; }
}

View File

@ -20,9 +20,9 @@
extern "C" int raw_write_str(const char *str);
/**
* Define context area
* Define stack area
*/
Genode::addr_t _context_area_start;
Genode::addr_t _stack_area_start;
enum { verbose_atexit = false };
@ -137,7 +137,7 @@ namespace Genode {
struct Thread_meta_data
{
/**
* Filled out by 'thread_start' function in the context of the new
* Filled out by 'thread_start' function in the stack of the new
* thread
*/
Thread_base * const thread_base;
@ -419,7 +419,7 @@ Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size,
PERR("pthread_create failed (returned %d, errno=%d)",
ret, errno);
destroy(env()->heap(), _tid.meta_data);
throw Context_alloc_failed();
throw Out_of_stack_space();
}
_tid.meta_data->wait_for_construction();

View File

@ -241,17 +241,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0xa0000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
struct Native_pd_args { };

View File

@ -18,9 +18,9 @@ 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
SRC_CC += thread/thread.cc thread/thread_context.cc thread/trace.cc
SRC_CC += thread/thread.cc thread/stack.cc thread/trace.cc
SRC_CC += thread/myself.cc
SRC_CC += thread/context_allocator.cc env/cap_map.cc
SRC_CC += thread/stack_allocator.cc env/cap_map.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc
SRC_CC += thread/thread_nova.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc

View File

@ -18,6 +18,9 @@
#include <base/rpc_server.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
@ -213,7 +216,7 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
throw Cpu_session::Thread_creation_failed();
/* prepare portal receive window of new thread */
if (!_rcv_buf.prepare_rcv_window((Nova::Utcb *)&_context->utcb))
if (!_rcv_buf.prepare_rcv_window((Nova::Utcb *)&_stack->utcb()))
throw Cpu_session::Thread_creation_failed();
if (start_on_construction)

View File

@ -1,5 +1,5 @@
/*
* \brief Thread-context specific part of the thread library
* \brief Stack-specific part of the thread library
* \author Norman Feske
* \author Alexander Boettcher
* \author Martin Stein
@ -21,6 +21,9 @@
#include <base/env.h>
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* base-nova includes */
#include <base/cap_map.h>
@ -37,8 +40,8 @@ Native_utcb * main_thread_utcb()
{
using namespace Genode;
return reinterpret_cast<Native_utcb *>(
Native_config::context_area_virtual_base() +
Native_config::context_virtual_size() - Nova::PAGE_SIZE_BYTE);
Native_config::stack_area_virtual_base() +
Native_config::stack_virtual_size() - Nova::PAGE_SIZE_BYTE);
}
@ -119,5 +122,5 @@ Native_utcb *Thread_base::utcb()
*/
if (this == 0) return main_thread_utcb();
return &_context->utcb;
return &_stack->utcb();
}

View File

@ -18,10 +18,12 @@
#include <base/printf.h>
#include <base/sleep.h>
#include <base/env.h>
#include <base/rpc_client.h>
#include <session/session.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */
#include <nova/syscalls.h>
#include <nova/util.h>
@ -99,7 +101,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
* afterwards.
*/
Rights rwx(true, true, true);
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
revoke(Mem_crd(utcb >> 12, 0, rwx));
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
@ -177,7 +179,7 @@ void Thread_base::start()
try { _cpu_session->state(_thread_cap, state); }
catch (...) { throw Cpu_session::Thread_creation_failed(); }
if (_cpu_session->start(_thread_cap, thread_ip, _context->stack_top()))
if (_cpu_session->start(_thread_cap, thread_ip, _stack->top()))
throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */

View File

@ -21,6 +21,9 @@
#include <base/native_types.h>
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <pager.h>
#include <address_space.h>
@ -43,10 +46,10 @@ namespace Genode {
VCPU = 0x2U,
WORKER = 0x4U,
};
uint8_t _features;
uint8_t _priority;
uint8_t _features;
uint8_t _priority;
char _name[Thread_base::Context::NAME_LEN];
Stack::Name _name;
addr_t _sel_ec() const { return _id_base; }
addr_t _sel_pt_oom() const { return _id_base + 1; }

View File

@ -126,13 +126,13 @@ static void page_fault_handler()
pf_type & Ipc_pager::ERR_W ? "W" : "w",
pf_type & Ipc_pager::ERR_P ? "P" : "p");
if ((Native_config::context_area_virtual_base() <= pf_sp) &&
(pf_sp < Native_config::context_area_virtual_base() +
Native_config::context_area_virtual_size()))
if ((Native_config::stack_area_virtual_base() <= pf_sp) &&
(pf_sp < Native_config::stack_area_virtual_base() +
Native_config::stack_area_virtual_size()))
{
addr_t utcb_addr_f = pf_sp / Native_config::context_virtual_size();
utcb_addr_f *= Native_config::context_virtual_size();
utcb_addr_f += Native_config::context_virtual_size();
addr_t utcb_addr_f = pf_sp / Native_config::stack_virtual_size();
utcb_addr_f *= Native_config::stack_virtual_size();
utcb_addr_f += Native_config::stack_virtual_size();
utcb_addr_f -= 4096;
Nova::Utcb * utcb_fault = reinterpret_cast<Nova::Utcb *>(utcb_addr_f);
@ -397,9 +397,9 @@ Platform::Platform() :
/* preserve Bios Data Area (BDA) in core's virtual address space */
region_alloc()->remove_range(BDA_VIRT_ADDR, 0x1000);
/* preserve context area in core's virtual address space */
region_alloc()->remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
/* preserve stack area in core's virtual address space */
region_alloc()->remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
/* exclude utcb of core pager thread + empty guard pages before and after */
region_alloc()->remove_range(CORE_PAGER_UTCB_ADDR - get_page_size(),
@ -420,14 +420,14 @@ Platform::Platform() :
};
for (unsigned i = 0; i < sizeof(check) / sizeof(check[0]); i++) {
if (Native_config::context_area_virtual_base() <= check[i] &&
check[i] < Native_config::context_area_virtual_base() +
Native_config::context_area_virtual_size())
if (Native_config::stack_area_virtual_base() <= check[i] &&
check[i] < Native_config::stack_area_virtual_base() +
Native_config::stack_area_virtual_size())
{
PERR("overlapping area - [%lx, %lx) vs %lx",
Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_base() +
Native_config::context_area_virtual_size(), check[i]);
Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_base() +
Native_config::stack_area_virtual_size(), check[i]);
nova_die();
}
}

View File

@ -119,8 +119,8 @@ int Platform_thread::start(void *ip, void *sp)
_sel_exc_base = is_vcpu() ? _pager->exc_pt_vcpu() : _pager->exc_pt_sel_client();
if (!is_vcpu()) {
pd_utcb = Native_config::context_area_virtual_base() +
Native_config::context_virtual_size() - get_page_size();
pd_utcb = Native_config::stack_area_virtual_base() +
Native_config::stack_virtual_size() - get_page_size();
addr_t remap_src[] = { _pd->parent_pt_sel(), _pager->Object_pool<Pager_object>::Entry::cap().local_name() };
addr_t remap_dst[] = { PT_SEL_PARENT, PT_SEL_MAIN_PAGER };
@ -315,7 +315,7 @@ Native_capability Platform_thread::single_step(bool on)
unsigned long Platform_thread::pager_object_badge() const
{
return reinterpret_cast<unsigned long>(_name);
return reinterpret_cast<unsigned long>(_name.string());
}
@ -353,17 +353,16 @@ Platform_thread::Platform_thread(const char *name, unsigned prio, int thread_id)
_pd(0), _pager(0), _id_base(cap_map()->insert(2)),
_sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0, 0, 0),
_features(0),
_priority(Cpu_session::scale_priority(Nova::Qpd::DEFAULT_PRIORITY, prio))
_priority(Cpu_session::scale_priority(Nova::Qpd::DEFAULT_PRIORITY, prio)),
_name(name)
{
strncpy(_name, name, sizeof(_name));
if (_priority == 0) {
PWRN("priority of thread '%s' below minimum - boost to 1", _name);
PWRN("priority of thread '%s' below minimum - boost to 1", _name.string());
_priority = 1;
}
if (_priority > Nova::Qpd::DEFAULT_PRIORITY) {
PWRN("priority of thread '%s' above maximum - limit to %u",
_name, Nova::Qpd::DEFAULT_PRIORITY);
_name.string(), Nova::Qpd::DEFAULT_PRIORITY);
_priority = Nova::Qpd::DEFAULT_PRIORITY;
}
}

View File

@ -3,7 +3,7 @@ LIBS = base-common core
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = context_area.cc \
SRC_CC = stack_area.cc \
core_mem_alloc.cc \
core_printf.cc \
core_rm_session.cc \
@ -61,6 +61,6 @@ vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR)/spec/x86
vpath context_area.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core

View File

@ -17,6 +17,9 @@
#include <base/thread.h>
#include <base/printf.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */
#include <nova/syscalls.h>
@ -74,7 +77,7 @@ void Thread_base::_deinit_platform_thread()
/* revoke utcb */
Nova::Rights rwx(true, true, true);
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
Nova::revoke(Nova::Mem_crd(utcb >> 12, 0, rwx));
}
@ -87,9 +90,9 @@ void Thread_base::start()
*/
using namespace Nova;
addr_t sp = _context->stack_top();
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb);
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_context->utcb);
addr_t sp = _stack->top();
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_stack->utcb());
addr_t pd_sel = Platform_pd::pd_core_sel();
/*

View File

@ -74,7 +74,7 @@ namespace Genode {
/**
* Empty UTCB type expected by the thread library, unused on OKL4
*
* On this kernel, UTCBs are not placed within the the context area. Each
* On this kernel, UTCBs are not placed within the stack area. Each
* thread can request its own UTCB pointer using the kernel interface.
*/
typedef struct { } Native_utcb;
@ -93,17 +93,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
struct Native_pd_args { };

View File

@ -21,7 +21,7 @@ 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
SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -1,6 +1,6 @@
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc

View File

@ -271,9 +271,9 @@ Platform::Platform() :
/* I/O port allocator (only meaningful for x86) */
_io_port_alloc.add_range(0, 0x10000);
/* preserve context area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
/* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
_vm_start = 0x1000;
_vm_size = 0xb0000000 - 0x1000;

View File

@ -4,7 +4,7 @@ LIBS += boot_info base-common
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += context_area.cc \
SRC_CC += stack_area.cc \
core_mem_alloc.cc \
core_printf.cc \
core_rm_session.cc \
@ -59,7 +59,7 @@ vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <platform.h>
#include <core_env.h>
@ -35,7 +38,7 @@ void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform_specific()->thread_slab())
Platform_thread(0, _context->name);
Platform_thread(0, _stack->name().string());
if (platform_specific()->core_pd()->bind_thread(_tid.pt))
throw Cpu_session::Thread_creation_failed();

View File

@ -65,8 +65,8 @@ namespace Genode {
/**
* Empty UTCB type expected by the thread library
*
* On this kernel, UTCBs are not placed within the the context area. Each
* thread can request its own UTCB pointer using the kernel interface.
* On this kernel, UTCBs are not placed within the stack area. Each thread
* can request its own UTCB pointer using the kernel interface.
*/
typedef struct { } Native_utcb;
@ -77,17 +77,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack area configuration
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
struct Native_pd_args { };

View File

@ -21,7 +21,7 @@ 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
SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc
SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc

View File

@ -434,8 +434,8 @@ void Platform::_setup_mem_alloc()
} else {
region.start = addr; region.end = addr + size;
if (region.intersects(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size()) ||
if (region.intersects(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size()) ||
intersects_kip_archdep(kip, addr, size)) {
unmap_local(region.start, size >> get_page_size_log2());
} else {
@ -563,11 +563,11 @@ void Platform::_setup_basics()
L4_MemoryDescLow(md), L4_MemoryDescHigh(md));
}
/* configure core's virtual memory, exclude KIP, context area */
/* configure core's virtual memory, exclude KIP, stack area */
_region_alloc.add_range(_vm_start, _vm_size);
_region_alloc.remove_range((addr_t)kip, kip_size);
_region_alloc.remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
_region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
/* remove KIP and MBI area from region and IO_MEM allocator */
remove_region(Region((addr_t)kip, (addr_t)kip + kip_size), _region_alloc);

View File

@ -4,7 +4,7 @@ LIBS = base-common
GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = context_area.cc \
SRC_CC = stack_area.cc \
core_printf.cc \
core_rpc_cap_alloc.cc \
cpu_session_component.cc \
@ -58,7 +58,7 @@ vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
vpath stack_area.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <platform.h>
#include <core_env.h>
@ -35,7 +38,7 @@ void Thread_base::start()
{
/* create and start platform thread */
_tid.pt = new(platform()->core_mem_alloc())
Platform_thread(0, _context->name);
Platform_thread(0, _stack->name().string());
platform_specific()->core_pd()->bind_thread(_tid.pt);

View File

@ -129,17 +129,17 @@ namespace Genode {
struct Native_config
{
/**
* Thread-context area configuration.
* Stack-area configuration.
*/
static constexpr addr_t context_area_virtual_base() {
static constexpr addr_t stack_area_virtual_base() {
return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() {
static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; }
/**
* Size of virtual address region holding the context of one thread
* Size of virtual address region holding the stack of one thread
*/
static constexpr addr_t context_virtual_size() { return 0x00100000UL; }
static constexpr addr_t stack_virtual_size() { return 0x00100000UL; }
};
struct Native_pd_args { };

View File

@ -21,7 +21,7 @@ SRC_CC += server/server.cc server/common.cc
SRC_CC += thread/thread.cc
SRC_CC += thread/trace.cc
SRC_CC += thread/myself.cc
SRC_CC += thread/context_allocator.cc
SRC_CC += thread/stack_allocator.cc
SRC_CC += thread/thread_bootstrap.cc
SRC_CC += env/capability.cc
SRC_CC += sleep.cc

View File

@ -7,7 +7,7 @@
LIBS += base-common syscall
SRC_CC += console/log_console.cc
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
SRC_CC += env/env.cc env/stack_area.cc env/reinitialize.cc
SRC_CC += env/capability_space.cc
SRC_CC += thread/thread_start.cc thread/thread_init.cc
SRC_CC += irq/platform.cc

View File

@ -30,7 +30,7 @@ SRC_CC += \
core_mem_alloc.cc \
core_rpc_cap_alloc.cc \
dump_alloc.cc \
context_area.cc \
stack_area.cc \
capability_space.cc \
pager.cc \
pager_ep.cc

View File

@ -15,6 +15,9 @@
#include <base/thread.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
/*****************************
** Startup library support **
@ -32,6 +35,6 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
void Genode::Thread_base::_thread_bootstrap()
{
if (tid().ep_sel == 0) {
tid().ep_sel = _context->utcb.ep_sel;
tid().ep_sel = _stack->utcb().ep_sel;
}
}

View File

@ -45,7 +45,7 @@ class Genode::Platform_thread : public List<Platform_thread>::Element
* Virtual address of the IPC buffer within the PDs address space
*
* The value is 0 for the PD's main thread. For all other threads,
* the value is somewhere within the context area.
* the value is somewhere within the stack area.
*/
addr_t const _utcb;

View File

@ -155,9 +155,9 @@ void Platform::_init_allocators()
core_virt_beg, core_virt_end, core_size);
}
/* preserve context area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(Native_config::context_area_virtual_base(),
Native_config::context_area_virtual_size());
/* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(Native_config::stack_area_virtual_base(),
Native_config::stack_area_virtual_size());
}

View File

@ -65,7 +65,7 @@ int Platform_pd::bind_thread(Platform_thread *thread)
* 'Vm_space'. In contrast to mapping that are created as a result of
* the RM-session's page-fault resolution, the IPC buffer's mapping
* won't be recoverable once flushed. For this reason, it is important
* to attach the UTCB as a dataspace to the context-area to make the RM
* to attach the UTCB as a dataspace to the stack area to make the RM
* session aware to the mapping. This code is missing.
*/
if (thread->_utcb) {

View File

@ -29,18 +29,17 @@ using namespace Genode;
/**
* Region-manager session for allocating thread contexts
* Region-manager session for allocating stacks
*
* This class corresponds to the managed dataspace that is normally
* used for organizing thread contexts with the thread context area.
* In contrast to the ordinary implementation, core's version does
* not split between allocation of memory and virtual memory management.
* Due to the missing availability of "real" dataspaces and capabilities
* refering to it without having an entrypoint in place, the allocation
* of a dataspace has no effect, but the attachment of the thereby "empty"
* dataspace is doing both: allocation and attachment.
* This class corresponds to the managed dataspace that is normally used for
* organizing stacks with the stack area. In contrast to the ordinary
* implementation, core's version does not split between allocation of memory
* and virtual memory management. Due to the missing availability of "real"
* dataspaces and capabilities refering to it without having an entrypoint in
* place, the allocation of a dataspace has no effect, but the attachment of
* the thereby "empty" dataspace is doing both: allocation and attachment.
*/
class Context_area_rm_session : public Rm_session
class Stack_area_rm_session : public Rm_session
{
private:
@ -54,7 +53,7 @@ class Context_area_rm_session : public Rm_session
public:
/**
* Allocate and attach on-the-fly backing store to thread-context area
* Allocate and attach on-the-fly backing store to the stack area
*/
Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */
size_t size, off_t offset,
@ -72,12 +71,12 @@ class Context_area_rm_session : public Rm_session
Dataspace_component *ds = new (&_ds_slab)
Dataspace_component(size, 0, phys, CACHED, true, 0);
if (!ds) {
PERR("dataspace for core context does not exist");
PERR("dataspace for core stack does not exist");
return (addr_t)0;
}
addr_t const core_local_addr =
Native_config::context_area_virtual_base() + (addr_t)local_addr;
Native_config::stack_area_virtual_base() + (addr_t)local_addr;
if (verbose)
PDBG("core_local_addr = %lx, phys_addr = %lx, size = 0x%zx",
@ -110,7 +109,7 @@ class Context_area_rm_session : public Rm_session
};
class Context_area_ram_session : public Ram_session
class Stack_area_ram_session : public Ram_session
{
public:
@ -136,15 +135,15 @@ class Context_area_ram_session : public Ram_session
*/
namespace Genode {
Rm_session *env_context_area_rm_session()
Rm_session *env_stack_area_rm_session()
{
static Context_area_rm_session inst;
static Stack_area_rm_session inst;
return &inst;
}
Ram_session *env_context_area_ram_session()
Ram_session *env_stack_area_ram_session()
{
static Context_area_ram_session inst;
static Stack_area_ram_session inst;
return &inst;
}
}

View File

@ -16,6 +16,9 @@
#include <base/printf.h>
#include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */
#include <platform.h>
#include <platform_thread.h>
@ -26,7 +29,7 @@ using namespace Genode;
void Thread_base::_init_platform_thread(size_t, Type type)
{
addr_t const utcb_virt_addr = (addr_t)&_context->utcb;
addr_t const utcb_virt_addr = (addr_t)&_stack->utcb();
if (type == MAIN) {
_tid.tcb_sel = seL4_CapInitThreadTCB;

View File

@ -107,14 +107,14 @@ struct Genode::Env
/**
* Reinitialize main-thread object
*
* \param context_area_rm new RM session of the context area
* \param stack_area_rm new RM session of the context area
*
* This function is solely used for implementing fork semantics
* as provided by the Noux environment.
*
* \noapi
*/
virtual void reinit_main_thread(Rm_session_capability &) = 0;
virtual void reinit_main_thread(Rm_session_capability &stack_area_rm) = 0;
};

View File

@ -2,50 +2,10 @@
* \brief Thread interface
* \author Norman Feske
* \date 2006-04-28
*
* For storing thread-specific data (called thread context) such as the stack
* and thread-local data, there is a dedicated portion of the virtual address
* space. This portion is called thread-context area. Within the thread-context
* area, each thread has a fixed-sized slot, a thread context. The layout of
* each thread context looks as follows
*
* ; lower address
* ; ...
* ; ============================ <- aligned at the virtual context size
* ;
* ; empty
* ;
* ; ----------------------------
* ;
* ; stack
* ; (top) <- initial stack pointer
* ; ---------------------------- <- address of 'Context' object
* ; additional context members
* ; ----------------------------
* ; UTCB
* ; ============================ <- aligned at the virtual context size
* ; ...
* ; higher address
*
* On some platforms, a user-level thread-control block (UTCB) area contains
* data shared between the user-level thread and the kernel. It is typically
* used for transferring IPC message payload or for system-call arguments.
* The additional context members are a reference to the corresponding
* 'Thread_base' object and the name of the thread.
*
* The thread context is a virtual memory area, initially not backed by real
* memory. When a new thread is created, an empty thread context gets assigned
* to the new thread and populated with memory pages for the stack and the
* additional context members. Note that this memory is allocated from the RAM
* session of the process environment and not accounted for when using the
* 'sizeof()' operand on a 'Thread_base' object.
*
* A thread may be associated with more than one stack. Additional secondary
* stacks can be associated with a thread, and used for user level scheduling.
*/
/*
* Copyright (C) 2006-2013 Genode Labs GmbH
* Copyright (C) 2006-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.
@ -70,6 +30,7 @@ namespace Genode {
class Rm_session;
class Thread_base;
class Stack;
template <unsigned> class Thread;
}
@ -84,174 +45,24 @@ class Genode::Thread_base
{
public:
class Context_alloc_failed : public Exception { };
class Stack_too_large : public Exception { };
class Stack_alloc_failed : public Exception { };
/**
* Thread context located within the thread-context area
*
* The end of a thread context is placed virtual size aligned.
*/
struct Context
{
private:
/**
* Top of the stack is accessible via stack_top()
*
* Context provides the first word of the stack to prevent the
* overlapping of stack top and the 'stack_base' member.
*/
addr_t _stack[1];
public:
/**
* Top of stack
*
* The alignment constrains are enforced by the CPU-specific ABI.
*/
addr_t stack_top() const { return Abi::stack_align((addr_t)_stack); }
/**
* Ensure that the stack has a given size at the minimum
*
* \param size minimum stack size
*
* \throw Stack_too_large
* \throw Stack_alloc_failed
*/
void stack_size(size_t const size);
/**
* Virtual address of the start of the stack
*
* This address is pointing to the begin of the dataspace used
* for backing the thread context except for the UTCB (which is
* managed by the kernel).
*/
addr_t stack_base;
/**
* Pointer to corresponding 'Thread_base' object
*/
Thread_base *thread_base;
/**
* Dataspace containing the backing store for the thread context
*
* We keep the dataspace capability to be able to release the
* backing store on thread destruction.
*/
Ram_dataspace_capability ds_cap;
/**
* Maximum length of thread name, including null-termination
*/
enum { NAME_LEN = 64 };
/**
* Thread name, used for debugging
*/
char name[NAME_LEN];
/*
* <- end of regular memory area
*
* The following part of the thread context is backed by
* kernel-managed memory. No member variables are allowed
* beyond this point.
*/
/**
* Kernel-specific user-level thread control block
*/
Native_utcb utcb;
};
class Out_of_stack_space : public Exception { };
class Stack_too_large : public Exception { };
class Stack_alloc_failed : public Exception { };
private:
/**
* Manage the allocation of thread contexts
*
* There exists only one instance of this class per process.
*/
class Context_allocator
{
private:
static constexpr size_t MAX_THREADS =
Native_config::context_area_virtual_size() /
Native_config::context_virtual_size();
struct Context_bit_allocator : Bit_allocator<MAX_THREADS>
{
Context_bit_allocator()
{
/* the first index is used by main thread */
_reserve(0, 1);
}
} _alloc;
Lock _threads_lock;
public:
/**
* Allocate thread context for specified thread
*
* \param thread thread for which to allocate the new context
* \param main_thread wether to alloc for the main thread
*
* \return virtual address of new thread context, or
* 0 if the allocation failed
*/
Context *alloc(Thread_base *thread, bool main_thread);
/**
* Release thread context
*/
void free(Context *thread);
/**
* Return 'Context' object for a given base address
*/
static Context *base_to_context(addr_t base);
/**
* Return base address of context containing the specified address
*/
static addr_t addr_to_base(void *addr);
/**
* Return index in context area for a given base address
*/
static size_t base_to_idx(addr_t base);
/**
* Return base address of context given index in context area
*/
static addr_t idx_to_base(size_t idx);
};
/**
* Return thread-context allocator
*/
static Context_allocator *_context_allocator();
/**
* Allocate and locally attach a new thread context
* Allocate and locally attach a new stack
*
* \param stack_size size of this threads stack
* \param main_thread wether this is the main thread
*/
Context *_alloc_context(size_t stack_size, bool main_thread);
Stack *_alloc_stack(size_t stack_size, char const *name, bool main_thread);
/**
* Detach and release thread context of the thread
* Detach and release stack of the thread
*/
void _free_context(Context *context);
void _free_stack(Stack *stack);
/**
* Platform-specific thread-startup code
@ -297,9 +108,9 @@ class Genode::Thread_base
Trace::Control *_trace_control;
/**
* Pointer to primary thread context
* Pointer to primary stack
*/
Context *_context;
Stack *_stack;
/**
* Physical thread ID
@ -345,10 +156,10 @@ class Genode::Thread_base
*
* \noapi
*
* FIXME: With type = Forked_main_thread the whole
* Context::_alloc_context call gets skipped but we should
* at least set Context::ds_cap in a way that it references
* the dataspace of the already attached stack.
* FIXME: With type = Forked_main_thread the stack allocation
* gets skipped but we should at least set Stack::ds_cap in a
* way that it references the dataspace of the already attached
* stack.
*/
Thread_base(size_t weight, const char *name, size_t stack_size,
Type type);
@ -362,12 +173,12 @@ class Genode::Thread_base
*
* \throw Stack_too_large
* \throw Stack_alloc_failed
* \throw Context_alloc_failed
* \throw Out_of_stack_space
*
* The stack for the new thread will be allocated from the RAM session
* of the process environment. A small portion of the stack size is
* internally used by the framework for storing thread-context
* information such as the thread's name ('Context').
* of the component environment. A small portion of the stack size is
* internally used by the framework for storing thread-specific
* information such as the thread's name.
*/
Thread_base(size_t weight, const char *name, size_t stack_size)
: Thread_base(weight, name, stack_size, NORMAL) { }
@ -389,7 +200,7 @@ class Genode::Thread_base
*
* \throw Stack_too_large
* \throw Stack_alloc_failed
* \throw Context_alloc_failed
* \throw Out_of_stack_space
*/
Thread_base(size_t weight, const char *name, size_t stack_size,
Type type, Cpu_session *);
@ -422,13 +233,12 @@ class Genode::Thread_base
*
* \throw Stack_too_large
* \throw Stack_alloc_failed
* \throw Context_alloc_failed
* \throw Out_of_stack_space
*
* The stack for the new thread will be allocated from the RAM
* session of the process environment. A small portion of the
* session of the component environment. A small portion of the
* stack size is internally used by the framework for storing
* thread-context information such as the thread's name (see
* 'struct Context').
* thread-specific information such as the thread's name.
*
* \return pointer to the new stack's top
*/
@ -461,14 +271,14 @@ class Genode::Thread_base
*
* \return pointer just after first stack element
*/
void *stack_top() const { return (void *)_context->stack_top(); }
void *stack_top() const;
/**
* Return base of stack
*
* \return pointer to last stack element
*/
void *stack_base() { return (void*)_context->stack_base; }
void *stack_base() const;
/**
* Return 'Thread_base' object corresponding to the calling thread
@ -482,10 +292,10 @@ class Genode::Thread_base
*
* \param size minimum stack size
*
* \throw Context::Stack_too_large
* \throw Context::Stack_alloc_failed
* \throw Stack_too_large
* \throw Stack_alloc_failed
*/
void stack_size(size_t const size) { _context->stack_size(size); }
void stack_size(size_t const size);
/**
* Return user-level thread control block

View File

@ -22,7 +22,7 @@ namespace Abi {
* On ARM we align the stack top to 16-byte. As a call (or branch) will not
* change the stack pointer, we need no further stack adjustment.
*/
static Genode::addr_t stack_align(Genode::addr_t addr) {
static inline Genode::addr_t stack_align(Genode::addr_t addr) {
return (addr & ~0xf); }
/**

View File

@ -41,7 +41,7 @@ namespace Abi {
* growth of the stack, we further adjust the stack-top address to comply
* to the AMD64 ABI rule "stack top + adjustment is 16-byte aligned".
*/
static Genode::addr_t stack_align(Genode::addr_t addr) {
inline Genode::addr_t stack_align(Genode::addr_t addr) {
return (addr & ~0xf) - sizeof(Genode::addr_t); }
/**

View File

@ -13,7 +13,7 @@ LD_OPT += -Bsymbolic-functions --version-script=$(DIR)/symbol.map
ifneq ($(filter linux, $(SPECS)),)
ENTRY_POINT = _start_initial_stack
LD_OPT += -T$(call select_from_repositories,src/ld/context_area.nostdlib.ld) \
LD_OPT += -T$(call select_from_repositories,src/ld/stack_area.nostdlib.ld) \
ifneq ($(filter x86_32, $(SPECS)),)
LD_OPT += -T$(DIR)/linux-32.ld

View File

@ -28,7 +28,7 @@ namespace Genode
{
extern bool inhibit_tracing;
Rm_session * env_context_area_rm_session();
Rm_session * env_stack_area_rm_session();
}
@ -83,12 +83,12 @@ void Genode::Platform_env::reinit(Native_capability::Dst dst,
void
Genode::Platform_env::
reinit_main_thread(Rm_session_capability & context_area_rm)
reinit_main_thread(Rm_session_capability & stack_area_rm)
{
/* reinitialize context area RM session */
Rm_session * const rms = env_context_area_rm_session();
/* reinitialize stack area RM session */
Rm_session * const rms = env_stack_area_rm_session();
Rm_session_client * const rmc = dynamic_cast<Rm_session_client *>(rms);
construct_at<Rm_session_client>(rmc, context_area_rm);
construct_at<Rm_session_client>(rmc, stack_area_rm);
/* reinitialize main-thread object */
::reinit_main_thread();

View File

@ -1,5 +1,5 @@
/*
* \brief Process-local thread-context area
* \brief Component-local stack area
* \author Norman Feske
* \date 2010-01-19
*/
@ -36,13 +36,13 @@ struct Expanding_rm_connection : Connection<Rm_session>, Expanding_rm_session_cl
};
struct Context_area_rm_session : Expanding_rm_connection
struct Stack_area_rm_session : Expanding_rm_connection
{
Context_area_rm_session()
: Expanding_rm_connection(0, Native_config::context_area_virtual_size())
Stack_area_rm_session()
: Expanding_rm_connection(0, Native_config::stack_area_virtual_size())
{
addr_t local_base = Native_config::context_area_virtual_base();
size_t size = Native_config::context_area_virtual_size();
addr_t local_base = Native_config::stack_area_virtual_base();
size_t size = Native_config::stack_area_virtual_size();
env()->rm_session()->attach_at(dataspace(), local_base, size);
}
@ -51,13 +51,13 @@ struct Context_area_rm_session : Expanding_rm_connection
namespace Genode {
Rm_session *env_context_area_rm_session()
Rm_session *env_stack_area_rm_session()
{
static Context_area_rm_session inst;
static Stack_area_rm_session inst;
return &inst;
}
Ram_session *env_context_area_ram_session()
Ram_session *env_stack_area_ram_session()
{
return env()->ram_session();
}

View File

@ -1,78 +0,0 @@
/*
* \brief Context-allocator implementation for the Genode Thread API
* \author Norman Feske
* \author Martin Stein
* \date 2014-01-26
*/
/*
* Copyright (C) 2010-2014 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.
*/
/* Genode includes */
#include <base/thread.h>
using namespace Genode;
Thread_base::Context *Thread_base::Context_allocator::base_to_context(addr_t base)
{
addr_t result = base + Native_config::context_virtual_size()
- sizeof(Context);
return reinterpret_cast<Context *>(result);
}
addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::context_virtual_size() - 1);
}
size_t Thread_base::Context_allocator::base_to_idx(addr_t base)
{
return (base - Native_config::context_area_virtual_base()) /
Native_config::context_virtual_size();
}
addr_t Thread_base::Context_allocator::idx_to_base(size_t idx)
{
return Native_config::context_area_virtual_base() +
idx * Native_config::context_virtual_size();
}
Thread_base::Context *
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
if (main_thread)
/* the main-thread context is the first one */
return base_to_context(Native_config::context_area_virtual_base());
try {
Lock::Guard _lock_guard(_threads_lock);
return base_to_context(idx_to_base(_alloc.alloc()));
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
void Thread_base::Context_allocator::free(Context *context)
{
addr_t const base = addr_to_base(context);
Lock::Guard _lock_guard(_threads_lock);
_alloc.free(base_to_idx(base));
}
Thread_base::Context_allocator *Thread_base::_context_allocator()
{
static Context_allocator context_allocator_inst;
return &context_allocator_inst;
}

View File

@ -11,24 +11,28 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack_allocator.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
* If the stack pointer is outside the stack 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())
if (sp < Native_config::stack_area_virtual_base() ||
sp >= Native_config::stack_area_virtual_base() +
Native_config::stack_area_virtual_size())
return 0;
addr_t base = Context_allocator::addr_to_base(&dummy);
return Context_allocator::base_to_context(base)->thread_base;
addr_t base = Stack_allocator::addr_to_base(&dummy);
return &Stack_allocator::base_to_stack(base)->thread();
}

View File

@ -0,0 +1,78 @@
/*
* \brief Stack-allocator implementation for the Genode Thread API
* \author Norman Feske
* \author Martin Stein
* \date 2014-01-26
*/
/*
* Copyright (C) 2010-2014 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.
*/
/* base-internal includes */
#include <base/internal/stack_allocator.h>
using namespace Genode;
Stack *Stack_allocator::base_to_stack(addr_t base)
{
addr_t result = base + Native_config::stack_virtual_size()
- sizeof(Stack);
return reinterpret_cast<Stack *>(result);
}
addr_t Stack_allocator::addr_to_base(void *addr)
{
return ((addr_t)addr) & ~(Native_config::stack_virtual_size() - 1);
}
size_t Stack_allocator::base_to_idx(addr_t base)
{
return (base - Native_config::stack_area_virtual_base()) /
Native_config::stack_virtual_size();
}
addr_t Stack_allocator::idx_to_base(size_t idx)
{
return Native_config::stack_area_virtual_base() +
idx * Native_config::stack_virtual_size();
}
Stack *
Stack_allocator::alloc(Thread_base *thread_base, bool main_thread)
{
if (main_thread)
/* the main-thread stack is the first one */
return base_to_stack(Native_config::stack_area_virtual_base());
try {
Lock::Guard _lock_guard(_threads_lock);
return base_to_stack(idx_to_base(_alloc.alloc()));
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
return 0;
}
}
void Stack_allocator::free(Stack *stack)
{
addr_t const base = addr_to_base(stack);
Lock::Guard _lock_guard(_threads_lock);
_alloc.free(base_to_idx(base));
}
Stack_allocator &Stack_allocator::stack_allocator()
{
static Stack_allocator inst;
return inst;
}

View File

@ -11,93 +11,102 @@
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <util/construct_at.h>
#include <util/string.h>
#include <util/misc_math.h>
#include <base/thread.h>
#include <base/env.h>
#include <base/sleep.h>
#include <base/snprintf.h>
#include <util/string.h>
#include <util/misc_math.h>
/* base-internal includes */
#include <base/internal/stack_allocator.h>
using namespace Genode;
/**
* Return the managed dataspace holding the thread context area
* Return the managed dataspace holding the stack 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();
Rm_session *env_stack_area_rm_session();
Ram_session *env_stack_area_ram_session();
}
void Thread_base::Context::stack_size(size_t const size)
void Stack::size(size_t const size)
{
/* check if the stack needs to be enhanced */
size_t const stack_size = (addr_t)_stack - stack_base;
size_t const stack_size = (addr_t)_stack - _base;
if (stack_size >= size) { return; }
/* check if the stack enhancement fits the context region */
/* check if the stack enhancement fits the stack region */
enum {
CONTEXT_SIZE = Native_config::context_virtual_size(),
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);
addr_t const stack_slot_base = Stack_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(); }
if (_base - ds_size < stack_slot_base)
throw Thread_base::Stack_too_large();
/* allocate and attach backing store for the stack enhancement */
addr_t const ds_addr = stack_base - ds_size -
Native_config::context_area_virtual_base();
addr_t const ds_addr = _base - ds_size -
Native_config::stack_area_virtual_base();
try {
Ram_session * const ram = env_context_area_ram_session();
Ram_session * const ram = env_stack_area_ram_session();
Ram_dataspace_capability const ds_cap = ram->alloc(ds_size);
Rm_session * const rm = env_context_area_rm_session();
Rm_session * const rm = env_stack_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;
if (ds_addr != (addr_t)attach_addr)
throw Thread_base::Out_of_stack_space();
}
catch (Ram_session::Alloc_failed) {
throw Thread_base::Stack_alloc_failed();
}
/* update stack information */
_base -= ds_size;
}
Thread_base::Context *
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
Stack *
Thread_base::_alloc_stack(size_t stack_size, char const *name, bool main_thread)
{
/*
* Synchronize context list when creating new threads from multiple threads
* Synchronize stack 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();
/* allocate stack */
Stack *stack = Stack_allocator::stack_allocator().alloc(this, main_thread);
if (!stack)
throw Out_of_stack_space();
/* determine size of dataspace to allocate for context members and stack */
/* determine size of dataspace to allocate for the 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() -
if (stack_size >= Native_config::stack_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.
* The stack pointer is always located at the top of the stack header.
*/
addr_t ds_addr = Context_allocator::addr_to_base(context) +
Native_config::context_virtual_size() -
addr_t ds_addr = Stack_allocator::addr_to_base(stack) +
Native_config::stack_virtual_size() -
ds_size;
/* add padding for UTCB if defined for the platform */
@ -107,50 +116,46 @@ Thread_base::_alloc_context(size_t stack_size, bool main_thread)
/* 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))
ds_cap = env_stack_area_ram_session()->alloc(ds_size);
addr_t attach_addr = ds_addr - Native_config::stack_area_virtual_base();
if (attach_addr != (addr_t)env_stack_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.
* Now the stack 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.
* We need to initialize the stack 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;
construct_at<Stack>(stack, name, *this, ds_addr, ds_cap);
Abi::init_stack(context->stack_top());
return context;
Abi::init_stack(stack->top());
return stack;
}
void Thread_base::_free_context(Context* context)
void Thread_base::_free_stack(Stack *stack)
{
addr_t ds_addr = context->stack_base - Native_config::context_area_virtual_base();
Ram_dataspace_capability ds_cap = context->ds_cap;
addr_t ds_addr = stack->base() - Native_config::stack_area_virtual_base();
Ram_dataspace_capability ds_cap = stack->ds_cap();
/* call de-constructor explicitly before memory gets detached */
context->~Context();
stack->~Stack();
Genode::env_context_area_rm_session()->detach((void *)ds_addr);
Genode::env_context_area_ram_session()->free(ds_cap);
Genode::env_stack_area_rm_session()->detach((void *)ds_addr);
Genode::env_stack_area_ram_session()->free(ds_cap);
/* context area ready for reuse */
_context_allocator()->free(context);
/* stack ready for reuse */
Stack_allocator::stack_allocator().free(stack);
}
void Thread_base::name(char *dst, size_t dst_len)
{
snprintf(dst, min(dst_len, (size_t)Context::NAME_LEN), "%s", _context->name);
snprintf(dst, dst_len, "%s", _stack->name().string());
}
@ -159,29 +164,36 @@ 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();
Stack *stack = _alloc_stack(stack_size, name, false);
return (void *)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));
addr_t base = Stack_allocator::addr_to_base(stack_addr);
_free_stack(Stack_allocator::base_to_stack(base));
}
void *Thread_base::stack_top() const { return (void *)_stack->top(); }
void *Thread_base::stack_base() const { return (void*)_stack->base(); }
void Thread_base::stack_size(size_t const size) { _stack->size(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),
_trace_control(nullptr),
_context(type == REINITIALIZED_MAIN ?
_context : _alloc_context(stack_size, type == MAIN)),
_stack(type == REINITIALIZED_MAIN ?
_stack : _alloc_stack(stack_size, name, type == MAIN)),
_join_lock(Lock::LOCKED)
{
strncpy(_context->name, name, sizeof(_context->name));
_init_platform_thread(weight, type);
if (_cpu_session) {
@ -201,12 +213,12 @@ Thread_base::~Thread_base()
{
if (Thread_base::myself() == this) {
PERR("thread '%s' tried to self de-struct - sleeping forever.",
_context->name);
_stack->name().string());
sleep_forever();
}
_deinit_platform_thread();
_free_context(_context);
_free_stack(_stack);
/*
* We have to detach the trace control dataspace last because

View File

@ -17,6 +17,9 @@
#include <base/sleep.h>
#include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
using namespace Genode;
@ -55,7 +58,7 @@ void Thread_base::start()
char buf[48];
name(buf, sizeof(buf));
enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
addr_t const utcb = (addr_t)&_context->utcb;
addr_t const utcb = (addr_t)&_stack->utcb();
_thread_cap = _cpu_session->create_thread(WEIGHT, buf, utcb);
if (!_thread_cap.valid())
throw Cpu_session::Thread_creation_failed();
@ -72,7 +75,7 @@ void Thread_base::start()
_cpu_session->set_pager(_thread_cap, pager_cap);
/* register initial IP and SP at core */
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
_cpu_session->start(_thread_cap, (addr_t)_thread_start, _stack->top());
}

View File

@ -0,0 +1,26 @@
/*
* \brief Fiasco-specific implementation of the thread API
* \author Norman Feske
* \date 2016-01-23
*/
/*
* 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.
*/
/* Genode includes */
#include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack.h>
using namespace Genode;
Native_utcb *Thread_base::utcb()
{
return &_stack->utcb();
}

View File

@ -28,18 +28,18 @@ using namespace Genode;
/**
* Region-manager session for allocating thread contexts
* Region-manager session for allocating stacks
*
* This class corresponds to the managed dataspace that is normally
* used for organizing thread contexts with the thread context area.
* used for organizing stacks within the stack area.
* In contrast to the ordinary implementation, core's version does
* not split between allocation of memory and virtual memory management.
* Due to the missing availability of "real" dataspaces and capabilities
* refering to it without having an entrypoint in place, the allocation
* referring to it without having an entrypoint in place, the allocation
* of a dataspace has no effect, but the attachment of the thereby "empty"
* dataspace is doing both: allocation and attachment.
*/
class Context_area_rm_session : public Rm_session
class Stack_area_rm_session : public Rm_session
{
private:
@ -53,7 +53,7 @@ class Context_area_rm_session : public Rm_session
public:
/**
* Allocate and attach on-the-fly backing store to thread-context area
* Allocate and attach on-the-fly backing store to stack area
*/
Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */
size_t size, off_t offset,
@ -66,7 +66,7 @@ class Context_area_rm_session : public Rm_session
Range_allocator *ra = platform_specific()->ram_alloc();
if (ra->alloc_aligned(size, &phys_base,
get_page_size_log2()).is_error()) {
PERR("could not allocate backing store for new context");
PERR("could not allocate backing store for new stack");
return (addr_t)0;
}
@ -76,11 +76,11 @@ class Context_area_rm_session : public Rm_session
Dataspace_component *ds = new (&_ds_slab)
Dataspace_component(size, 0, (addr_t)phys_base, CACHED, true, 0);
if (!ds) {
PERR("dataspace for core context does not exist");
PERR("dataspace for core stack does not exist");
return (addr_t)0;
}
addr_t core_local_addr = Native_config::context_area_virtual_base() +
addr_t core_local_addr = Native_config::stack_area_virtual_base() +
(addr_t)local_addr;
if (verbose)
@ -103,15 +103,14 @@ class Context_area_rm_session : public Rm_session
{
using Genode::addr_t;
if ((addr_t)local_addr >= Native_config::context_area_virtual_size())
if ((addr_t)local_addr >= Native_config::stack_area_virtual_size())
return;
addr_t const detach = Native_config::context_area_virtual_base() +
addr_t const detach = Native_config::stack_area_virtual_base() +
(addr_t)local_addr;
addr_t const thread_context = Native_config::context_virtual_size();
addr_t const pages = ((detach & ~(thread_context - 1))
+ thread_context
- detach) >> get_page_size_log2();
addr_t const stack = Native_config::stack_virtual_size();
addr_t const pages = ((detach & ~(stack - 1)) + stack - detach)
>> get_page_size_log2();
unmap_local(detach, pages);
}
@ -129,7 +128,7 @@ class Context_area_rm_session : public Rm_session
};
class Context_area_ram_session : public Ram_session
class Stack_area_ram_session : public Ram_session
{
public:
@ -154,15 +153,15 @@ class Context_area_ram_session : public Ram_session
*/
namespace Genode {
Rm_session *env_context_area_rm_session()
Rm_session *env_stack_area_rm_session()
{
static Context_area_rm_session inst;
static Stack_area_rm_session inst;
return &inst;
}
Ram_session *env_context_area_ram_session()
Ram_session *env_stack_area_ram_session()
{
static Context_area_ram_session inst;
static Stack_area_ram_session inst;
return &inst;
}
}

Some files were not shown because too many files have changed in this diff Show More