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 * 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. * thread can request its own UTCB pointer using the kernel interface.
*/ */
typedef struct { } Native_utcb; typedef struct { } Native_utcb;
@ -76,17 +76,17 @@ namespace Genode {
struct Native_config 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; } return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 { }; 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 += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/context_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.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 += thread/thread_start.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.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; region.start = addr; region.end = addr + size;
if (!region.intersects(Native_config::context_area_virtual_base(), if (!region.intersects(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size())) { Native_config::stack_area_virtual_size())) {
add_region(region, _ram_alloc); add_region(region, _ram_alloc);
add_region(region, _core_address_ranges()); add_region(region, _core_address_ranges());
} }
@ -411,9 +411,9 @@ void Platform::_setup_basics()
_vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start; _vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start;
_region_alloc.add_range(_vm_start, _vm_size); _region_alloc.add_range(_vm_start, _vm_size);
/* preserve context area in core's virtual address space */ /* preserve stack area in core's virtual address space */
_region_alloc.remove_range(Native_config::context_area_virtual_base(), _region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); Native_config::stack_area_virtual_size());
/* I/O memory could be the whole user address space */ /* I/O memory could be the whole user address space */
/* FIXME if the kernel helps to find out max address - use info here */ /* 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 GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += context_area.cc \ SRC_CC += stack_area.cc \
core_printf.cc \ core_printf.cc \
core_rpc_cap_alloc.cc \ core_rpc_cap_alloc.cc \
cpu_session_component.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 trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_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_object.cc $(GEN_CORE_DIR) vpath pager_object.cc $(GEN_CORE_DIR)
vpath pager_ep.cc $(GEN_CORE_DIR) vpath pager_ep.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

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

View File

@ -82,9 +82,29 @@ namespace Fiasco {
namespace Genode { namespace Genode {
typedef Fiasco::l4_cap_idx_t Native_thread_id; 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_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 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 */ 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 */ unsigned exceptions; /* counts exceptions raised by the thread */
bool paused; /* indicates whether thread is stopped */ bool paused; /* indicates whether thread is stopped */
bool in_exception; /* true if thread is in exception */ bool in_exception; /* true if thread is in exception */

View File

@ -53,7 +53,7 @@ namespace Genode {
_sem = call<Rpc_request_semaphore>(); _sem = call<Rpc_request_semaphore>();
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0, l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
Thread_base::myself()->tid()); Thread_base::myself()->tid().kcap);
if (l4_error(tag)) if (l4_error(tag))
PERR("l4_irq_attach failed with %ld!", 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 * \author Stefan Kalkowski
* \date 2014-01-24 * \date 2014-01-24
*/ */
@ -21,17 +21,17 @@ namespace Genode {
struct Native_config 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; } return 0x20000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 * \author Stefan Kalkowski
* \date 2014-01-24 * \date 2014-01-24
*/ */
@ -21,17 +21,17 @@ namespace Genode {
struct Native_config 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; } return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/myself.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 += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.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 env/cap_map_remove.cc env/cap_alloc.cc
SRC_CC += thread/thread_start.cc SRC_CC += thread/thread_start.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc

View File

@ -19,6 +19,9 @@
#include <base/sleep.h> #include <base/sleep.h>
#include <base/env.h> #include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
namespace Fiasco { namespace Fiasco {
#include <l4/sys/utcb.h> #include <l4/sys/utcb.h>
} }
@ -30,8 +33,8 @@ void Thread_base::_deinit_platform_thread()
{ {
using namespace Fiasco; using namespace Fiasco;
if (_context->utcb && _thread_cap.valid()) { if (_tid.kcap && _thread_cap.valid()) {
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(_context->utcb)->user[UTCB_TCR_BADGE]; Cap_index *i = (Cap_index*)l4_utcb_tcr_u(utcb()->foc_utcb)->user[UTCB_TCR_BADGE];
cap_map()->remove(i); cap_map()->remove(i);
_cpu_session->kill_thread(_thread_cap); _cpu_session->kill_thread(_thread_cap);
env()->rm_session()->remove_client(_pager_cap); env()->rm_session()->remove_client(_pager_cap);
@ -59,7 +62,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
return; return;
} }
/* adjust values whose computation differs for a main thread */ /* 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(); _thread_cap = env()->parent()->main_thread_cap();
if (!_thread_cap.valid()) if (!_thread_cap.valid())
@ -83,15 +86,19 @@ void Thread_base::start()
Thread_state state; Thread_state state;
try { state = _cpu_session->state(_thread_cap); } try { state = _cpu_session->state(_thread_cap); }
catch (...) { throw Cpu_session::Thread_creation_failed(); } 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); 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(foc_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_THREAD_OBJ] = (addr_t)this;
/* register initial IP and SP at core */ /* 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) { auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) return; 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); l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state);
if (l4_msgtag_has_error(tag)) 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) { auto lambda = [&] (Cpu_thread_component *thread) {
if (!thread) return; 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 }; enum { THREAD_SINGLE_STEP = 0x40000 };
int flags = enable ? THREAD_SINGLE_STEP : 0; int flags = enable ? THREAD_SINGLE_STEP : 0;

View File

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

View File

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

View File

@ -42,7 +42,7 @@ namespace Genode {
Cap_mapping _gate; Cap_mapping _gate;
Cap_mapping _pager; Cap_mapping _pager;
Cap_mapping _irq; Cap_mapping _irq;
Native_utcb _utcb; addr_t _utcb;
char _name[32]; /* thread name that will be char _name[32]; /* thread name that will be
registered at the kernel registered at the kernel
debugger */ debugger */
@ -185,7 +185,7 @@ namespace Genode {
Cap_mapping& gate() { return _gate; } Cap_mapping& gate() { return _gate; }
const char *name() const { return _name; } const char *name() const { return _name; }
bool core_thread() const { return _core_thread; } 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; 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); &label, L4_IPC_SEND_TIMEOUT_0);
int err = l4_ipc_error(_tag, l4_utcb()); int err = l4_ipc_error(_tag, l4_utcb());
if (err) { if (err) {
@ -119,7 +119,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup() 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 */ /* 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); 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() void Ipc_pager::acknowledge_exception()
{ {
memcpy(l4_utcb_exc(), &_regs, sizeof(l4_exc_regs_t)); 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); 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(); void entry();
static Native_thread handler_cap() static Fiasco::l4_cap_idx_t handler_cap()
{ {
static Interrupt_handler handler; static Interrupt_handler handler;
return handler._thread_cap.dst(); return handler._thread_cap.dst();

View File

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

View File

@ -327,8 +327,8 @@ void Platform::_setup_mem_alloc()
} }
region.start = addr; region.end = addr + size; region.start = addr; region.end = addr + size;
if (!region.intersects(Native_config::context_area_virtual_base(), if (!region.intersects(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size())) { Native_config::stack_area_virtual_size())) {
add_region(region, _ram_alloc); add_region(region, _ram_alloc);
add_region(region, _core_address_ranges()); add_region(region, _core_address_ranges());
} }
@ -402,9 +402,9 @@ void Platform::_setup_basics()
_vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start; _vm_start = _vm_start == 0 ? L4_PAGESIZE : _vm_start;
_region_alloc.add_range(_vm_start, _vm_size); _region_alloc.add_range(_vm_start, _vm_size);
/* preserve context area in core's virtual address space */ /* preserve stack area in core's virtual address space */
_region_alloc.remove_range(Native_config::context_area_virtual_base(), _region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); Native_config::stack_area_virtual_size());
/* preserve utcb- area in core's virtual address space */ /* preserve utcb- area in core's virtual address space */
_region_alloc.remove_range((addr_t)l4_utcb(), L4_PAGESIZE * 16); _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]) if (_threads[i])
continue; continue;
_threads[i] = thread; _threads[i] = thread;
if (thread->core_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 else
thread->_utcb = thread->_utcb =
reinterpret_cast<l4_utcb_t*>(utcb_area_start() + i * L4_UTCB_OFFSET); reinterpret_cast<addr_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; Fiasco::l4_cap_idx_t cap_offset = THREAD_AREA_BASE + i * THREAD_AREA_SLOT;
thread->_pager.remote = cap_offset + THREAD_PAGER_CAP;
thread->_irq.remote = cap_offset + THREAD_IRQ_CAP; 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 it's no core-thread we have to map parent and pager gate cap */
if (!thread->core_thread()) { 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_start();
l4_thread_control_pager(_pager.remote); l4_thread_control_pager(_pager.remote);
l4_thread_control_exc_handler(_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()); l4_msgtag_t tag = l4_thread_control_commit(_thread.local.dst());
if (l4_msgtag_has_error(tag)) { if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_control_commit for %lx failed!", PWRN("l4_thread_control_commit for %lx failed!",

View File

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

View File

@ -16,6 +16,9 @@
#include <base/thread.h> #include <base/thread.h>
#include <base/sleep.h> #include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */ /* core includes */
#include <platform.h> #include <platform.h>
#include <core_env.h> #include <core_env.h>
@ -43,19 +46,24 @@ void Thread_base::start()
/* create and start platform thread */ /* create and start platform thread */
Platform_thread *pt = 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)) if (platform_specific()->core_pd()->bind_thread(pt))
throw Cpu_session::Thread_creation_failed(); 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 = _thread_cap =
reinterpret_cap_cast<Cpu_thread>(Native_capability(pt->thread().local)); reinterpret_cap_cast<Cpu_thread>(Native_capability(pt->thread().local));
pt->pager(platform_specific()->core_pager()); pt->pager(platform_specific()->core_pager());
_context->utcb = pt->utcb(); l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx();
l4_utcb_tcr_u(pt->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;
l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
pt->start((void *)_thread_start, stack_top()); 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) static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
{ {
Genode::Native_thread_id tid = thread_base ? Genode::Native_thread_id tid = thread_base ?
thread_base->tid() : thread_base->tid().kcap :
Fiasco::MAIN_THREAD_CAP; Fiasco::MAIN_THREAD_CAP;
Genode::Native_thread_id irq = tid + Fiasco::THREAD_IRQ_CAP; Genode::Native_thread_id irq = tid + Fiasco::THREAD_IRQ_CAP;
Fiasco::l4_irq_trigger(irq); 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) static inline void thread_switch_to(Genode::Thread_base *thread_base)
{ {
Genode::Native_thread_id tid = thread_base ? Genode::Native_thread_id tid = thread_base ?
thread_base->tid() : thread_base->tid().kcap :
Fiasco::MAIN_THREAD_CAP; Fiasco::MAIN_THREAD_CAP;
Fiasco::l4_thread_switch(tid); Fiasco::l4_thread_switch(tid);
} }
@ -82,7 +82,7 @@ static void thread_stop_myself()
Genode::Thread_base *myself = Genode::Thread_base::myself(); Genode::Thread_base *myself = Genode::Thread_base::myself();
Genode::Native_thread_id tid = myself ? Genode::Native_thread_id tid = myself ?
myself->tid() : myself->tid().kcap :
Fiasco::MAIN_THREAD_CAP; Fiasco::MAIN_THREAD_CAP;
Genode::Native_thread_id irq = tid + THREAD_IRQ_CAP; Genode::Native_thread_id irq = tid + THREAD_IRQ_CAP;
l4_irq_receive(irq, L4_IPC_NEVER); l4_irq_receive(irq, L4_IPC_NEVER);

View File

@ -19,6 +19,7 @@
#include <kernel/log.h> #include <kernel/log.h>
#include <base/native_capability.h> #include <base/native_capability.h>
#include <base/ipc_msgbuf.h> #include <base/ipc_msgbuf.h>
#include <base/printf.h>
namespace Genode namespace Genode
{ {
@ -80,17 +81,17 @@ struct Genode::Native_region
struct Genode::Native_config 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; } return 0xe0000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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: private:
Kernel::capid_t _caps[MAX_CAP_ARGS]; /* capability buffer */ Kernel::capid_t _caps[MAX_CAP_ARGS]; /* capability buffer */
size_t _cap_cnt = 0; /* capability counter */ size_t _cap_cnt; /* capability counter */
size_t _size = 0; /* bytes to transfer */ size_t _size; /* bytes to transfer */
uint8_t _buf[get_page_size() - sizeof(_caps) - uint8_t _buf[get_page_size() - sizeof(_caps) -
sizeof(_cap_cnt) - sizeof(_size)]; 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 * 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 * controlled by the RM session, because it is needed before the main
* thread can access its RM session. * 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/myself.cc
SRC_CC += thread/bootstrap.cc SRC_CC += thread/bootstrap.cc
SRC_CC += thread/trace.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 += kernel/interface.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += rm_session_client.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 += console/log_console.cc
SRC_CC += cpu/cache.cc SRC_CC += cpu/cache.cc
SRC_CC += env/env.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 += env/reinitialize.cc
SRC_CC += thread/start.cc SRC_CC += thread/start.cc
SRC_CC += irq/platform.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.cc
SRC_CC += platform_pd.cc SRC_CC += platform_pd.cc
SRC_CC += platform_thread.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_component.cc
SRC_CC += ram_session_support.cc SRC_CC += ram_session_support.cc
SRC_CC += rm_session_component.cc SRC_CC += rm_session_component.cc

View File

@ -17,6 +17,9 @@
#include <base/env.h> #include <base/env.h>
#include <base/sleep.h> #include <base/sleep.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* base-hw includes */ /* base-hw includes */
#include <kernel/interface.h> #include <kernel/interface.h>
@ -57,9 +60,9 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
** Thread_base ** ** 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(); return utcb_main_thread();
} }

View File

@ -18,9 +18,12 @@
#include <base/sleep.h> #include <base/sleep.h>
#include <base/env.h> #include <base/env.h>
/* base-internal includes */
#include <base/internal/stack_allocator.h>
using namespace Genode; using namespace Genode;
namespace Genode { Rm_session * env_context_area_rm_session(); } namespace Genode { Rm_session * env_stack_area_rm_session(); }
namespace Hw { namespace Hw {
extern Ram_dataspace_capability _main_thread_utcb_ds; 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 */ /* create server object */
char buf[48]; char buf[48];
name(buf, sizeof(buf)); 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); _thread_cap = _cpu_session->create_thread(weight, buf, utcb);
return; return;
} }
/* if we got reinitialized we have to get rid of the old UTCB */ /* if we got reinitialized we have to get rid of the old UTCB */
size_t const utcb_size = sizeof(Native_utcb); size_t const utcb_size = sizeof(Native_utcb);
addr_t const context_area = Native_config::context_area_virtual_base(); addr_t const stack_area = Native_config::stack_area_virtual_base();
addr_t const utcb_new = (addr_t)&_context->utcb - context_area; addr_t const utcb_new = (addr_t)&_stack->utcb() - stack_area;
Rm_session * const rm = env_context_area_rm_session(); Rm_session * const rm = env_stack_area_rm_session();
if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); } 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); } try { rm->attach_at(Hw::_main_thread_utcb_ds, utcb_new, utcb_size); }
catch(...) { catch(...) {
PERR("failed to re-map UTCB"); PERR("failed to re-map UTCB");
@ -69,12 +73,12 @@ void Thread_base::_deinit_platform_thread()
_cpu_session->kill_thread(_thread_cap); _cpu_session->kill_thread(_thread_cap);
/* detach userland thread-context */ /* detach userland stack */
size_t const size = sizeof(_context->utcb); size_t const size = sizeof(_stack->utcb());
addr_t utcb = Context_allocator::addr_to_base(_context) + addr_t utcb = Stack_allocator::addr_to_base(_stack) +
Native_config::context_virtual_size() - size - Native_config::stack_virtual_size() - size -
Native_config::context_area_virtual_base(); Native_config::stack_area_virtual_base();
env_context_area_rm_session()->detach(utcb); env_stack_area_rm_session()->detach(utcb);
if (_pager_cap.valid()) { if (_pager_cap.valid()) {
env()->rm_session()->remove_client(_pager_cap); env()->rm_session()->remove_client(_pager_cap);
@ -91,20 +95,20 @@ void Thread_base::start()
_pager_cap = env()->rm_session()->add_client(_thread_cap); _pager_cap = env()->rm_session()->add_client(_thread_cap);
_cpu_session->set_pager(_thread_cap, _pager_cap); _cpu_session->set_pager(_thread_cap, _pager_cap);
/* attach userland thread-context */ /* attach userland stack */
try { try {
Ram_dataspace_capability ds = _cpu_session->utcb(_thread_cap); Ram_dataspace_capability ds = _cpu_session->utcb(_thread_cap);
size_t const size = sizeof(_context->utcb); size_t const size = sizeof(_stack->utcb());
addr_t dst = Context_allocator::addr_to_base(_context) + addr_t dst = Stack_allocator::addr_to_base(_stack) +
Native_config::context_virtual_size() - size - Native_config::stack_virtual_size() - size -
Native_config::context_area_virtual_base(); Native_config::stack_area_virtual_base();
env_context_area_rm_session()->attach_at(ds, dst, size); env_stack_area_rm_session()->attach_at(ds, dst, size);
} catch (...) { } catch (...) {
PERR("failed to attach userland thread-context"); PERR("failed to attach userland stack");
sleep_forever(); sleep_forever();
} }
/* start thread with its initial IP and aligned SP */ /* 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 quota CPU quota that shall be granted to the thread
* \param label debugging label * \param label debugging label
* \param virt_prio unscaled processor-scheduling priority * \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, Platform_thread(size_t const quota, const char * const label,
unsigned const virt_prio, addr_t const utcb); 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 */ /* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range( _core_mem_alloc.virt_alloc()->remove_range(
Native_config::context_area_virtual_base(), Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); Native_config::stack_area_virtual_size());
_init_io_port_alloc(); _init_io_port_alloc();

View File

@ -17,6 +17,9 @@
#include <base/sleep.h> #include <base/sleep.h>
#include <base/env.h> #include <base/env.h>
/* base-internal stack */
#include <base/internal/stack.h>
/* core includes */ /* core includes */
#include <map_local.h> #include <map_local.h>
#include <kernel/kernel.h> #include <kernel/kernel.h>
@ -25,11 +28,10 @@
using namespace Genode; 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() void Thread_base::start()
{ {
@ -56,13 +58,13 @@ void Thread_base::_init_platform_thread(size_t, Type type)
{ {
if (type == NORMAL) { if (type == NORMAL) {
_tid.platform_thread = new (platform()->core_mem_alloc()) _tid.platform_thread = new (platform()->core_mem_alloc())
Platform_thread(_context->name, &_context->utcb); Platform_thread(_stack->name().string(), &_stack->utcb());
return; 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(), 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)); max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
/* adjust initial object state in case of a main thread */ /* adjust initial object state in case of a main thread */

View File

@ -26,7 +26,7 @@
* Genode from POSIX. * Genode from POSIX.
*/ */
extern Genode::addr_t _context_area_start; extern Genode::addr_t _stack_area_start;
namespace Genode { namespace Genode {
@ -128,21 +128,21 @@ namespace Genode {
struct Native_config struct Native_config
{ {
/** /**
* Thread-context area configuration. * Stack area configuration
* *
* Please update platform-specific files after changing these * 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() { static addr_t stack_area_virtual_base() {
return align_addr((addr_t)&_context_area_start, 20); } 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; } 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 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 += env/rm_session_mmap.cc env/debug.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
SRC_CC += server/server.cc server/common.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 += irq/platform.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -10,7 +10,7 @@
LIBS += base-common syscall cxx LIBS += base-common syscall cxx
SRC_CC += console/log_console.cc 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 SRC_CC += server/rpc_cap_alloc.cc
INC_DIR += $(REP_DIR)/src/include $(BASE_DIR)/src/include 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 # 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. # the program under Linux to prevent clashes with vdso.
# #
ifneq ($(USE_HOST_LD_SCRIPT),yes) ifneq ($(USE_HOST_LD_SCRIPT),yes)
LD_TEXT_ADDR ?= 0x01000000 LD_TEXT_ADDR ?= 0x01000000
LD_SCRIPT_STATIC = $(call select_from_repositories,src/ld/genode.ld) \ 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 else
LD_SCRIPT_STATIC ?= LD_SCRIPT_STATIC ?=
endif endif

View File

@ -10,7 +10,7 @@ endif
# #
# We need to manually add the default linker script on the command line in case # 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 # 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) ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_STATIC = ldscripts/armelf_linux_eabi.xc 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 # 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 # 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) ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_DEFAULT = ldscripts/elf_i386.xc 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 # 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 # 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) ifeq ($(USE_HOST_LD_SCRIPT),yes)
LD_SCRIPT_DEFAULT = ldscripts/elf_x86_64.xc 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. * 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 * 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 * Later mappings are done by the Genode program itself, which knows nothing
* about these initial mappings. Therefore, most mmap() operations are _soft_ * about these initial mappings. Therefore, most mmap() operations are _soft_
* to detect region conflicts with existing mappings or let the kernel find * 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 * but not populated dataspaces are "holes" in the Linux VM space represented
* by PROT_NONE mappings (see _reserve_local()). * 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 * created and attached during program launch. The managed dataspace replaces
* the inital reserved area, which is therefore flushed beforehand. Hybrid * 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. * Note, we do not support nesting of managed dataspaces.
*/ */
@ -40,7 +40,7 @@
/* base-internal includes */ /* base-internal includes */
#include <base/internal/local_capability.h> #include <base/internal/local_capability.h>
#include <base/internal/platform_env.h> #include <base/internal/platform_env.h>
#include <base/internal/context_area.h> #include <base/internal/stack_area.h>
using namespace Genode; using namespace Genode;
@ -58,13 +58,13 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
addr_t local_addr, addr_t local_addr,
Genode::size_t size) Genode::size_t size)
{ {
/* special handling for context area */ /* special handling for stack area */
if (use_local_addr if (use_local_addr
&& local_addr == Native_config::context_area_virtual_base() && local_addr == Native_config::stack_area_virtual_base()
&& size == Native_config::context_area_virtual_size()) { && 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 * initial mapping preserved in linker script and apply the actual
* reservation. Subsequent requests are just ignored. * reservation. Subsequent requests are just ignored.
*/ */
@ -73,8 +73,8 @@ addr_t Platform_env_base::Rm_session_mmap::_reserve_local(bool use_loc
{ {
Context() Context()
{ {
flush_context_area(); flush_stack_area();
reserve_context_area(); reserve_stack_area();
} }
} inst; } inst;

View File

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

View File

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

View File

@ -18,29 +18,29 @@
#include <base/thread.h> #include <base/thread.h>
/* base-internal includes */ /* 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 * This class corresponds to the managed dataspace that is normally used for
* used for organizing thread contexts with the thread context area. * organizing stacks within the stack. It "emulates" the sub address space by
* It "emulates" the sub address space by adjusting the local address * adjusting the local address argument to 'attach' with the offset of the
* argument to 'attach' with the offset of the thread context area. * stack area.
*/ */
class Context_area_rm_session : public Genode::Rm_session class Stack_area_rm_session : public Genode::Rm_session
{ {
public: public:
Context_area_rm_session() Stack_area_rm_session()
{ {
flush_context_area(); flush_stack_area();
reserve_context_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, Local_addr attach(Genode::Dataspace_capability ds_cap,
Genode::size_t size, Genode::off_t offset, Genode::size_t size, Genode::off_t offset,
@ -49,9 +49,9 @@ class Context_area_rm_session : public Genode::Rm_session
{ {
using namespace Genode; 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_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 */ /* use anonymous mmap for allocating stack backing store */
int flags = MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE; 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) { 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) { Genode::Pager_capability add_client(Genode::Thread_capability) {
return Genode::Pager_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: 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 { 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; 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; return &inst;
} }
} }

View File

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

View File

@ -211,7 +211,7 @@ namespace Genode {
* the common use case of managed dataspaces as mechanism * the common use case of managed dataspaces as mechanism
* to reserve parts of the local address space from being * to reserve parts of the local address space from being
* populated by the 'env()->rm_session()'. (i.e., for the * 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) * shared-library segments)
*/ */
addr_t _base; 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 * \author Christian Helmuth
* \date 2013-09-26 * \date 2013-09-26
*/ */
@ -11,8 +11,8 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#ifndef _INCLUDE__BASE__INTERNAL__CONTEXT_AREA_H_ #ifndef _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
#define _INCLUDE__BASE__INTERNAL__CONTEXT_AREA_H_ #define _INCLUDE__BASE__INTERNAL__STACK_AREA_H_
/* Genode includes */ /* Genode includes */
#include <base/thread.h> #include <base/thread.h>
@ -24,12 +24,12 @@
#include <sys/mman.h> #include <sys/mman.h>
static inline void flush_context_area() static inline void flush_stack_area()
{ {
using namespace Genode; using namespace Genode;
void * const base = (void *) Native_config::context_area_virtual_base(); void * const base = (void *) Native_config::stack_area_virtual_base();
size_t const size = Native_config::context_area_virtual_size(); size_t const size = Native_config::stack_area_virtual_size();
int ret; int ret;
if ((ret = lx_munmap(base, size)) < 0) { 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; using namespace Genode;
int const flags = MAP_ANONYMOUS | MAP_PRIVATE; int const flags = MAP_ANONYMOUS | MAP_PRIVATE;
int const prot = PROT_NONE; int const prot = PROT_NONE;
size_t const size = Native_config::context_area_virtual_size(); size_t const size = Native_config::stack_area_virtual_size();
void * const addr_in = (void *)Native_config::context_area_virtual_base(); void * const addr_in = (void *)Native_config::stack_area_virtual_base();
void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0); void * const addr_out = lx_mmap(addr_in, size, prot, flags, -1, 0);
/* reserve at local address failed - unmap incorrect mapping */ /* 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; 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 PHDRS
{ {
context_area PT_LOAD FLAGS(0); stack_area PT_LOAD FLAGS(0);
} }
SECTIONS SECTIONS
{ {
. = 0x40000000; . = 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. * 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 SECTIONS
{ {
. = 0x40000000; . = 0x40000000;
_context_area_start = .; _stack_area_start = .;
.context_area : { . += 0x10000000; } .stack_area : { . += 0x10000000; }
} }

View File

@ -20,9 +20,9 @@
extern "C" int raw_write_str(const char *str); 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 }; enum { verbose_atexit = false };
@ -137,7 +137,7 @@ namespace Genode {
struct Thread_meta_data 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
*/ */
Thread_base * const thread_base; 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)", PERR("pthread_create failed (returned %d, errno=%d)",
ret, errno); ret, errno);
destroy(env()->heap(), _tid.meta_data); destroy(env()->heap(), _tid.meta_data);
throw Context_alloc_failed(); throw Out_of_stack_space();
} }
_tid.meta_data->wait_for_construction(); _tid.meta_data->wait_for_construction();

View File

@ -241,17 +241,17 @@ namespace Genode {
struct Native_config 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; } return 0xa0000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 { }; struct Native_pd_args { };

View File

@ -18,9 +18,9 @@ SRC_CC += elf/elf_binary.cc
SRC_CC += lock/lock.cc SRC_CC += lock/lock.cc
SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc SRC_CC += signal/signal.cc signal/common.cc signal/platform.cc
SRC_CC += server/server.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/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 += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.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 += thread/thread_nova.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc SRC_CC += server/rpc_cap_alloc.cc

View File

@ -18,6 +18,9 @@
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/env.h> #include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */ /* NOVA includes */
#include <nova/syscalls.h> #include <nova/syscalls.h>
#include <nova/util.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(); throw Cpu_session::Thread_creation_failed();
/* prepare portal receive window of new thread */ /* 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(); throw Cpu_session::Thread_creation_failed();
if (start_on_construction) 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 Norman Feske
* \author Alexander Boettcher * \author Alexander Boettcher
* \author Martin Stein * \author Martin Stein
@ -21,6 +21,9 @@
#include <base/env.h> #include <base/env.h>
#include <base/thread.h> #include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* base-nova includes */ /* base-nova includes */
#include <base/cap_map.h> #include <base/cap_map.h>
@ -37,8 +40,8 @@ Native_utcb * main_thread_utcb()
{ {
using namespace Genode; using namespace Genode;
return reinterpret_cast<Native_utcb *>( return reinterpret_cast<Native_utcb *>(
Native_config::context_area_virtual_base() + Native_config::stack_area_virtual_base() +
Native_config::context_virtual_size() - Nova::PAGE_SIZE_BYTE); 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(); 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/printf.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <base/env.h> #include <base/env.h>
#include <base/rpc_client.h> #include <base/rpc_client.h>
#include <session/session.h> #include <session/session.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */ /* NOVA includes */
#include <nova/syscalls.h> #include <nova/syscalls.h>
#include <nova/util.h> #include <nova/util.h>
@ -99,7 +101,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
* afterwards. * afterwards.
*/ */
Rights rwx(true, true, true); 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)); revoke(Mem_crd(utcb >> 12, 0, rwx));
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2); _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); } try { _cpu_session->state(_thread_cap, state); }
catch (...) { throw Cpu_session::Thread_creation_failed(); } 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(); throw Cpu_session::Thread_creation_failed();
/* request native EC thread cap */ /* request native EC thread cap */

View File

@ -21,6 +21,9 @@
#include <base/native_types.h> #include <base/native_types.h>
#include <base/thread.h> #include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* core includes */ /* core includes */
#include <pager.h> #include <pager.h>
#include <address_space.h> #include <address_space.h>
@ -43,10 +46,10 @@ namespace Genode {
VCPU = 0x2U, VCPU = 0x2U,
WORKER = 0x4U, WORKER = 0x4U,
}; };
uint8_t _features; uint8_t _features;
uint8_t _priority; uint8_t _priority;
char _name[Thread_base::Context::NAME_LEN]; Stack::Name _name;
addr_t _sel_ec() const { return _id_base; } addr_t _sel_ec() const { return _id_base; }
addr_t _sel_pt_oom() const { return _id_base + 1; } 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_W ? "W" : "w",
pf_type & Ipc_pager::ERR_P ? "P" : "p"); pf_type & Ipc_pager::ERR_P ? "P" : "p");
if ((Native_config::context_area_virtual_base() <= pf_sp) && if ((Native_config::stack_area_virtual_base() <= pf_sp) &&
(pf_sp < Native_config::context_area_virtual_base() + (pf_sp < Native_config::stack_area_virtual_base() +
Native_config::context_area_virtual_size())) Native_config::stack_area_virtual_size()))
{ {
addr_t utcb_addr_f = pf_sp / Native_config::context_virtual_size(); addr_t utcb_addr_f = pf_sp / Native_config::stack_virtual_size();
utcb_addr_f *= Native_config::context_virtual_size(); utcb_addr_f *= Native_config::stack_virtual_size();
utcb_addr_f += Native_config::context_virtual_size(); utcb_addr_f += Native_config::stack_virtual_size();
utcb_addr_f -= 4096; utcb_addr_f -= 4096;
Nova::Utcb * utcb_fault = reinterpret_cast<Nova::Utcb *>(utcb_addr_f); 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 */ /* preserve Bios Data Area (BDA) in core's virtual address space */
region_alloc()->remove_range(BDA_VIRT_ADDR, 0x1000); region_alloc()->remove_range(BDA_VIRT_ADDR, 0x1000);
/* preserve context area in core's virtual address space */ /* preserve stack area in core's virtual address space */
region_alloc()->remove_range(Native_config::context_area_virtual_base(), region_alloc()->remove_range(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); Native_config::stack_area_virtual_size());
/* exclude utcb of core pager thread + empty guard pages before and after */ /* exclude utcb of core pager thread + empty guard pages before and after */
region_alloc()->remove_range(CORE_PAGER_UTCB_ADDR - get_page_size(), 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++) { for (unsigned i = 0; i < sizeof(check) / sizeof(check[0]); i++) {
if (Native_config::context_area_virtual_base() <= check[i] && if (Native_config::stack_area_virtual_base() <= check[i] &&
check[i] < Native_config::context_area_virtual_base() + check[i] < Native_config::stack_area_virtual_base() +
Native_config::context_area_virtual_size()) Native_config::stack_area_virtual_size())
{ {
PERR("overlapping area - [%lx, %lx) vs %lx", PERR("overlapping area - [%lx, %lx) vs %lx",
Native_config::context_area_virtual_base(), Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_base() + Native_config::stack_area_virtual_base() +
Native_config::context_area_virtual_size(), check[i]); Native_config::stack_area_virtual_size(), check[i]);
nova_die(); 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(); _sel_exc_base = is_vcpu() ? _pager->exc_pt_vcpu() : _pager->exc_pt_sel_client();
if (!is_vcpu()) { if (!is_vcpu()) {
pd_utcb = Native_config::context_area_virtual_base() + pd_utcb = Native_config::stack_area_virtual_base() +
Native_config::context_virtual_size() - get_page_size(); 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_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 }; 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 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)), _pd(0), _pager(0), _id_base(cap_map()->insert(2)),
_sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0, 0, 0), _sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0, 0, 0),
_features(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) { 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; _priority = 1;
} }
if (_priority > Nova::Qpd::DEFAULT_PRIORITY) { if (_priority > Nova::Qpd::DEFAULT_PRIORITY) {
PWRN("priority of thread '%s' above maximum - limit to %u", 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; _priority = Nova::Qpd::DEFAULT_PRIORITY;
} }
} }

View File

@ -3,7 +3,7 @@ LIBS = base-common core
GEN_CORE_DIR = $(BASE_DIR)/src/core GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = context_area.cc \ SRC_CC = stack_area.cc \
core_mem_alloc.cc \ core_mem_alloc.cc \
core_printf.cc \ core_printf.cc \
core_rm_session.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 core_mem_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath platform_services.cc $(GEN_CORE_DIR)/spec/x86 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 core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core vpath %.cc $(REP_DIR)/src/core

View File

@ -17,6 +17,9 @@
#include <base/thread.h> #include <base/thread.h>
#include <base/printf.h> #include <base/printf.h>
/* base-internal includes */
#include <base/internal/stack.h>
/* NOVA includes */ /* NOVA includes */
#include <nova/syscalls.h> #include <nova/syscalls.h>
@ -74,7 +77,7 @@ void Thread_base::_deinit_platform_thread()
/* revoke utcb */ /* revoke utcb */
Nova::Rights rwx(true, true, true); 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)); Nova::revoke(Nova::Mem_crd(utcb >> 12, 0, rwx));
} }
@ -87,9 +90,9 @@ void Thread_base::start()
*/ */
using namespace Nova; using namespace Nova;
addr_t sp = _context->stack_top(); addr_t sp = _stack->top();
addr_t utcb = reinterpret_cast<addr_t>(&_context->utcb); addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_context->utcb); Utcb * utcb_obj = reinterpret_cast<Utcb *>(&_stack->utcb());
addr_t pd_sel = Platform_pd::pd_core_sel(); 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 * 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. * thread can request its own UTCB pointer using the kernel interface.
*/ */
typedef struct { } Native_utcb; typedef struct { } Native_utcb;
@ -93,17 +93,17 @@ namespace Genode {
struct Native_config 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; } return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 { }; 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 += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/context_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -1,6 +1,6 @@
SRC_CC += console/log_console.cc SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.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 += thread/thread_start.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc SRC_CC += server/rpc_cap_alloc.cc

View File

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

View File

@ -4,7 +4,7 @@ LIBS += boot_info base-common
GEN_CORE_DIR = $(BASE_DIR)/src/core GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC += context_area.cc \ SRC_CC += stack_area.cc \
core_mem_alloc.cc \ core_mem_alloc.cc \
core_printf.cc \ core_printf.cc \
core_rm_session.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_mem_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR)
vpath dump_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_ep.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR) vpath pager_object.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core vpath %.cc $(REP_DIR)/src/core

View File

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

View File

@ -65,8 +65,8 @@ namespace Genode {
/** /**
* Empty UTCB type expected by the thread library * 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 stack area. Each thread
* thread can request its own UTCB pointer using the kernel interface. * can request its own UTCB pointer using the kernel interface.
*/ */
typedef struct { } Native_utcb; typedef struct { } Native_utcb;
@ -77,17 +77,17 @@ namespace Genode {
struct Native_config 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; } return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 { }; 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 += server/server.cc server/common.cc
SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc
SRC_CC += thread/myself.cc SRC_CC += thread/myself.cc
SRC_CC += thread/context_allocator.cc SRC_CC += thread/stack_allocator.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc
SRC_CC += rm_session_client.cc SRC_CC += rm_session_client.cc

View File

@ -8,7 +8,7 @@ LIBS += base-common
SRC_CC += console/log_console.cc SRC_CC += console/log_console.cc
SRC_CC += cpu/cache.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 += thread/thread_start.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc
SRC_CC += server/rpc_cap_alloc.cc SRC_CC += server/rpc_cap_alloc.cc

View File

@ -434,8 +434,8 @@ void Platform::_setup_mem_alloc()
} else { } else {
region.start = addr; region.end = addr + size; region.start = addr; region.end = addr + size;
if (region.intersects(Native_config::context_area_virtual_base(), if (region.intersects(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()) || Native_config::stack_area_virtual_size()) ||
intersects_kip_archdep(kip, addr, size)) { intersects_kip_archdep(kip, addr, size)) {
unmap_local(region.start, size >> get_page_size_log2()); unmap_local(region.start, size >> get_page_size_log2());
} else { } else {
@ -563,11 +563,11 @@ void Platform::_setup_basics()
L4_MemoryDescLow(md), L4_MemoryDescHigh(md)); 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.add_range(_vm_start, _vm_size);
_region_alloc.remove_range((addr_t)kip, kip_size); _region_alloc.remove_range((addr_t)kip, kip_size);
_region_alloc.remove_range(Native_config::context_area_virtual_base(), _region_alloc.remove_range(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); Native_config::stack_area_virtual_size());
/* remove KIP and MBI area from region and IO_MEM allocator */ /* remove KIP and MBI area from region and IO_MEM allocator */
remove_region(Region((addr_t)kip, (addr_t)kip + kip_size), _region_alloc); 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 GEN_CORE_DIR = $(BASE_DIR)/src/core
SRC_CC = context_area.cc \ SRC_CC = stack_area.cc \
core_printf.cc \ core_printf.cc \
core_rpc_cap_alloc.cc \ core_rpc_cap_alloc.cc \
cpu_session_component.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 dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR) vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath core_rpc_cap_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_ep.cc $(GEN_CORE_DIR)
vpath pager_object.cc $(GEN_CORE_DIR) vpath pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console vpath core_printf.cc $(BASE_DIR)/src/base/console

View File

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

View File

@ -129,17 +129,17 @@ namespace Genode {
struct Native_config 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; } return 0x40000000UL; }
static constexpr addr_t context_area_virtual_size() { static constexpr addr_t stack_area_virtual_size() {
return 0x10000000UL; } 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 { }; 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/thread.cc
SRC_CC += thread/trace.cc SRC_CC += thread/trace.cc
SRC_CC += thread/myself.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 += thread/thread_bootstrap.cc
SRC_CC += env/capability.cc SRC_CC += env/capability.cc
SRC_CC += sleep.cc SRC_CC += sleep.cc

View File

@ -7,7 +7,7 @@
LIBS += base-common syscall LIBS += base-common syscall
SRC_CC += console/log_console.cc 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 += env/capability_space.cc
SRC_CC += thread/thread_start.cc thread/thread_init.cc SRC_CC += thread/thread_start.cc thread/thread_init.cc
SRC_CC += irq/platform.cc SRC_CC += irq/platform.cc

View File

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

View File

@ -15,6 +15,9 @@
#include <base/thread.h> #include <base/thread.h>
#include <base/env.h> #include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
/***************************** /*****************************
** Startup library support ** ** Startup library support **
@ -32,6 +35,6 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
void Genode::Thread_base::_thread_bootstrap() void Genode::Thread_base::_thread_bootstrap()
{ {
if (tid().ep_sel == 0) { 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 * 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 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; addr_t const _utcb;

View File

@ -155,9 +155,9 @@ void Platform::_init_allocators()
core_virt_beg, core_virt_end, core_size); core_virt_beg, core_virt_end, core_size);
} }
/* preserve context area in core's virtual address space */ /* preserve stack area in core's virtual address space */
_core_mem_alloc.virt_alloc()->remove_range(Native_config::context_area_virtual_base(), _core_mem_alloc.virt_alloc()->remove_range(Native_config::stack_area_virtual_base(),
Native_config::context_area_virtual_size()); 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 * '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 * the RM-session's page-fault resolution, the IPC buffer's mapping
* won't be recoverable once flushed. For this reason, it is important * 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. * session aware to the mapping. This code is missing.
*/ */
if (thread->_utcb) { 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 * This class corresponds to the managed dataspace that is normally used for
* used for organizing thread contexts with the thread context area. * organizing stacks with the stack area. In contrast to the ordinary
* In contrast to the ordinary implementation, core's version does * implementation, core's version does not split between allocation of memory
* not split between allocation of memory and virtual memory management. * and virtual memory management. Due to the missing availability of "real"
* Due to the missing availability of "real" dataspaces and capabilities * dataspaces and capabilities refering to it without having an entrypoint in
* refering to it without having an entrypoint in place, the allocation * place, the allocation of a dataspace has no effect, but the attachment of
* of a dataspace has no effect, but the attachment of the thereby "empty" * the thereby "empty" dataspace is doing both: allocation and attachment.
* dataspace is doing both: allocation and attachment.
*/ */
class Context_area_rm_session : public Rm_session class Stack_area_rm_session : public Rm_session
{ {
private: private:
@ -54,7 +53,7 @@ class Context_area_rm_session : public Rm_session
public: 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 */ Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */
size_t size, off_t offset, 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 *ds = new (&_ds_slab)
Dataspace_component(size, 0, phys, CACHED, true, 0); Dataspace_component(size, 0, phys, CACHED, true, 0);
if (!ds) { if (!ds) {
PERR("dataspace for core context does not exist"); PERR("dataspace for core stack does not exist");
return (addr_t)0; return (addr_t)0;
} }
addr_t const core_local_addr = 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) if (verbose)
PDBG("core_local_addr = %lx, phys_addr = %lx, size = 0x%zx", 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: public:
@ -136,15 +135,15 @@ class Context_area_ram_session : public Ram_session
*/ */
namespace Genode { 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; 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; return &inst;
} }
} }

View File

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

View File

@ -107,14 +107,14 @@ struct Genode::Env
/** /**
* Reinitialize main-thread object * 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 * This function is solely used for implementing fork semantics
* as provided by the Noux environment. * as provided by the Noux environment.
* *
* \noapi * \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 * \brief Thread interface
* \author Norman Feske * \author Norman Feske
* \date 2006-04-28 * \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 * This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
@ -70,6 +30,7 @@ namespace Genode {
class Rm_session; class Rm_session;
class Thread_base; class Thread_base;
class Stack;
template <unsigned> class Thread; template <unsigned> class Thread;
} }
@ -84,174 +45,24 @@ class Genode::Thread_base
{ {
public: public:
class Context_alloc_failed : public Exception { }; class Out_of_stack_space : public Exception { };
class Stack_too_large : public Exception { }; class Stack_too_large : public Exception { };
class Stack_alloc_failed : 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;
};
private: private:
/** /**
* Manage the allocation of thread contexts * Allocate and locally attach a new stack
*
* 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
* *
* \param stack_size size of this threads stack * \param stack_size size of this threads stack
* \param main_thread wether this is the main thread * \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 * Platform-specific thread-startup code
@ -297,9 +108,9 @@ class Genode::Thread_base
Trace::Control *_trace_control; Trace::Control *_trace_control;
/** /**
* Pointer to primary thread context * Pointer to primary stack
*/ */
Context *_context; Stack *_stack;
/** /**
* Physical thread ID * Physical thread ID
@ -345,10 +156,10 @@ class Genode::Thread_base
* *
* \noapi * \noapi
* *
* FIXME: With type = Forked_main_thread the whole * FIXME: With type = Forked_main_thread the stack allocation
* Context::_alloc_context call gets skipped but we should * gets skipped but we should at least set Stack::ds_cap in a
* at least set Context::ds_cap in a way that it references * way that it references the dataspace of the already attached
* the dataspace of the already attached stack. * stack.
*/ */
Thread_base(size_t weight, const char *name, size_t stack_size, Thread_base(size_t weight, const char *name, size_t stack_size,
Type type); Type type);
@ -362,12 +173,12 @@ class Genode::Thread_base
* *
* \throw Stack_too_large * \throw Stack_too_large
* \throw Stack_alloc_failed * \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 * 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 * of the component environment. A small portion of the stack size is
* internally used by the framework for storing thread-context * internally used by the framework for storing thread-specific
* information such as the thread's name ('Context'). * information such as the thread's name.
*/ */
Thread_base(size_t weight, const char *name, size_t stack_size) Thread_base(size_t weight, const char *name, size_t stack_size)
: Thread_base(weight, name, stack_size, NORMAL) { } : Thread_base(weight, name, stack_size, NORMAL) { }
@ -389,7 +200,7 @@ class Genode::Thread_base
* *
* \throw Stack_too_large * \throw Stack_too_large
* \throw Stack_alloc_failed * \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, Thread_base(size_t weight, const char *name, size_t stack_size,
Type type, Cpu_session *); Type type, Cpu_session *);
@ -422,13 +233,12 @@ class Genode::Thread_base
* *
* \throw Stack_too_large * \throw Stack_too_large
* \throw Stack_alloc_failed * \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 * 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 * stack size is internally used by the framework for storing
* thread-context information such as the thread's name (see * thread-specific information such as the thread's name.
* 'struct Context').
* *
* \return pointer to the new stack's top * \return pointer to the new stack's top
*/ */
@ -461,14 +271,14 @@ class Genode::Thread_base
* *
* \return pointer just after first stack element * \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 base of stack
* *
* \return pointer to last stack element * \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 * Return 'Thread_base' object corresponding to the calling thread
@ -482,10 +292,10 @@ class Genode::Thread_base
* *
* \param size minimum stack size * \param size minimum stack size
* *
* \throw Context::Stack_too_large * \throw Stack_too_large
* \throw Context::Stack_alloc_failed * \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 * 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 * 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. * 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); } return (addr & ~0xf); }
/** /**

View File

@ -41,7 +41,7 @@ namespace Abi {
* growth of the stack, we further adjust the stack-top address to comply * 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". * 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); } 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)),) ifneq ($(filter linux, $(SPECS)),)
ENTRY_POINT = _start_initial_stack 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)),) ifneq ($(filter x86_32, $(SPECS)),)
LD_OPT += -T$(DIR)/linux-32.ld LD_OPT += -T$(DIR)/linux-32.ld

View File

@ -28,7 +28,7 @@ namespace Genode
{ {
extern bool inhibit_tracing; 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 void
Genode::Platform_env:: 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 */ /* reinitialize stack area RM session */
Rm_session * const rms = env_context_area_rm_session(); Rm_session * const rms = env_stack_area_rm_session();
Rm_session_client * const rmc = dynamic_cast<Rm_session_client *>(rms); 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 */ /* reinitialize main-thread object */
::reinit_main_thread(); ::reinit_main_thread();

View File

@ -1,5 +1,5 @@
/* /*
* \brief Process-local thread-context area * \brief Component-local stack area
* \author Norman Feske * \author Norman Feske
* \date 2010-01-19 * \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() Stack_area_rm_session()
: Expanding_rm_connection(0, Native_config::context_area_virtual_size()) : Expanding_rm_connection(0, Native_config::stack_area_virtual_size())
{ {
addr_t local_base = Native_config::context_area_virtual_base(); addr_t local_base = Native_config::stack_area_virtual_base();
size_t size = Native_config::context_area_virtual_size(); size_t size = Native_config::stack_area_virtual_size();
env()->rm_session()->attach_at(dataspace(), local_base, size); env()->rm_session()->attach_at(dataspace(), local_base, size);
} }
@ -51,13 +51,13 @@ struct Context_area_rm_session : Expanding_rm_connection
namespace Genode { 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; return &inst;
} }
Ram_session *env_context_area_ram_session() Ram_session *env_stack_area_ram_session()
{ {
return env()->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. * under the terms of the GNU General Public License version 2.
*/ */
/* Genode includes */
#include <base/thread.h> #include <base/thread.h>
/* base-internal includes */
#include <base/internal/stack_allocator.h>
Genode::Thread_base *Genode::Thread_base::myself() Genode::Thread_base *Genode::Thread_base::myself()
{ {
int dummy = 0; /* used for determining the stack pointer */ 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 * we are the main thread because this condition can never met by any other
* thread. * thread.
*/ */
addr_t sp = (addr_t)(&dummy); addr_t sp = (addr_t)(&dummy);
if (sp < Native_config::context_area_virtual_base() || if (sp < Native_config::stack_area_virtual_base() ||
sp >= Native_config::context_area_virtual_base() + sp >= Native_config::stack_area_virtual_base() +
Native_config::context_area_virtual_size()) Native_config::stack_area_virtual_size())
return 0; return 0;
addr_t base = Context_allocator::addr_to_base(&dummy); addr_t base = Stack_allocator::addr_to_base(&dummy);
return Context_allocator::base_to_context(base)->thread_base; 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. * 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/thread.h>
#include <base/env.h> #include <base/env.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <base/snprintf.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; 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. * This function is provided by the process environment.
*/ */
namespace Genode { namespace Genode {
Rm_session *env_context_area_rm_session(); Rm_session *env_stack_area_rm_session();
Ram_session *env_context_area_ram_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 */ /* 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; } if (stack_size >= size) { return; }
/* check if the stack enhancement fits the context region */ /* check if the stack enhancement fits the stack region */
enum { enum {
CONTEXT_SIZE = Native_config::context_virtual_size(),
UTCB_SIZE = sizeof(Native_utcb), UTCB_SIZE = sizeof(Native_utcb),
PAGE_SIZE_LOG2 = 12, PAGE_SIZE_LOG2 = 12,
PAGE_SIZE = (1UL << PAGE_SIZE_LOG2), 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); 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 */ /* allocate and attach backing store for the stack enhancement */
addr_t const ds_addr = stack_base - ds_size - addr_t const ds_addr = _base - ds_size -
Native_config::context_area_virtual_base(); Native_config::stack_area_virtual_base();
try { 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); 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); 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 */ if (ds_addr != (addr_t)attach_addr)
stack_base -= ds_size; 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 * Stack *
Thread_base::_alloc_context(size_t stack_size, bool main_thread) 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 * XXX: remove interim fix
*/ */
static Lock alloc_lock; static Lock alloc_lock;
Lock::Guard _lock_guard(alloc_lock); Lock::Guard _lock_guard(alloc_lock);
/* allocate thread context */ /* allocate stack */
Context *context = _context_allocator()->alloc(this, main_thread); Stack *stack = Stack_allocator::stack_allocator().alloc(this, main_thread);
if (!context) if (!stack)
throw Context_alloc_failed(); 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 }; enum { PAGE_SIZE_LOG2 = 12 };
size_t ds_size = align_addr(stack_size, PAGE_SIZE_LOG2); 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)) sizeof(Native_utcb) - (1UL << PAGE_SIZE_LOG2))
throw Stack_too_large(); throw Stack_too_large();
/* /*
* Calculate base address of the stack * 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) + addr_t ds_addr = Stack_allocator::addr_to_base(stack) +
Native_config::context_virtual_size() - Native_config::stack_virtual_size() -
ds_size; ds_size;
/* add padding for UTCB if defined for the platform */ /* 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 */ /* allocate and attach backing store for the stack */
Ram_dataspace_capability ds_cap; Ram_dataspace_capability ds_cap;
try { try {
ds_cap = env_context_area_ram_session()->alloc(ds_size); ds_cap = env_stack_area_ram_session()->alloc(ds_size);
addr_t attach_addr = ds_addr - Native_config::context_area_virtual_base(); addr_t attach_addr = ds_addr - Native_config::stack_area_virtual_base();
if (attach_addr != (addr_t)env_context_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size)) if (attach_addr != (addr_t)env_stack_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size))
throw Stack_alloc_failed(); throw Stack_alloc_failed();
} }
catch (Ram_session::Alloc_failed) { 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 * Now the stack is backed by memory, so it is safe to access its members.
* members.
* *
* We need to initialize the context object's memory with zeroes, * We need to initialize the stack object's memory with zeroes, otherwise
* otherwise the ds_cap isn't invalid. That would cause trouble * the ds_cap isn't invalid. That would cause trouble when the assignment
* when the assignment operator of Native_capability is used. * operator of Native_capability is used.
*/ */
memset(context, 0, sizeof(Context) - sizeof(Context::utcb)); construct_at<Stack>(stack, name, *this, ds_addr, ds_cap);
context->thread_base = this;
context->stack_base = ds_addr;
context->ds_cap = ds_cap;
Abi::init_stack(context->stack_top()); Abi::init_stack(stack->top());
return context; 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(); addr_t ds_addr = stack->base() - Native_config::stack_area_virtual_base();
Ram_dataspace_capability ds_cap = context->ds_cap; Ram_dataspace_capability ds_cap = stack->ds_cap();
/* call de-constructor explicitly before memory gets detached */ /* call de-constructor explicitly before memory gets detached */
context->~Context(); stack->~Stack();
Genode::env_context_area_rm_session()->detach((void *)ds_addr); Genode::env_stack_area_rm_session()->detach((void *)ds_addr);
Genode::env_context_area_ram_session()->free(ds_cap); Genode::env_stack_area_ram_session()->free(ds_cap);
/* context area ready for reuse */ /* stack ready for reuse */
_context_allocator()->free(context); Stack_allocator::stack_allocator().free(stack);
} }
void Thread_base::name(char *dst, size_t dst_len) 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) void* Thread_base::alloc_secondary_stack(char const *name, size_t stack_size)
{ {
Context *context = _alloc_context(stack_size, false); Stack *stack = _alloc_stack(stack_size, name, false);
strncpy(context->name, name, sizeof(context->name)); return (void *)stack->top();
return (void *)context->stack_top();
} }
void Thread_base::free_secondary_stack(void* stack_addr) void Thread_base::free_secondary_stack(void* stack_addr)
{ {
addr_t base = Context_allocator::addr_to_base(stack_addr); addr_t base = Stack_allocator::addr_to_base(stack_addr);
_free_context(Context_allocator::base_to_context(base)); _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, Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size,
Type type, Cpu_session *cpu_session) Type type, Cpu_session *cpu_session)
: :
_cpu_session(cpu_session), _cpu_session(cpu_session),
_trace_control(nullptr), _trace_control(nullptr),
_context(type == REINITIALIZED_MAIN ? _stack(type == REINITIALIZED_MAIN ?
_context : _alloc_context(stack_size, type == MAIN)), _stack : _alloc_stack(stack_size, name, type == MAIN)),
_join_lock(Lock::LOCKED) _join_lock(Lock::LOCKED)
{ {
strncpy(_context->name, name, sizeof(_context->name));
_init_platform_thread(weight, type); _init_platform_thread(weight, type);
if (_cpu_session) { if (_cpu_session) {
@ -201,12 +213,12 @@ Thread_base::~Thread_base()
{ {
if (Thread_base::myself() == this) { if (Thread_base::myself() == this) {
PERR("thread '%s' tried to self de-struct - sleeping forever.", PERR("thread '%s' tried to self de-struct - sleeping forever.",
_context->name); _stack->name().string());
sleep_forever(); sleep_forever();
} }
_deinit_platform_thread(); _deinit_platform_thread();
_free_context(_context); _free_stack(_stack);
/* /*
* We have to detach the trace control dataspace last because * We have to detach the trace control dataspace last because

View File

@ -17,6 +17,9 @@
#include <base/sleep.h> #include <base/sleep.h>
#include <base/env.h> #include <base/env.h>
/* base-internal includes */
#include <base/internal/stack.h>
using namespace Genode; using namespace Genode;
@ -55,7 +58,7 @@ void Thread_base::start()
char buf[48]; char buf[48];
name(buf, sizeof(buf)); name(buf, sizeof(buf));
enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT }; 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); _thread_cap = _cpu_session->create_thread(WEIGHT, buf, utcb);
if (!_thread_cap.valid()) if (!_thread_cap.valid())
throw Cpu_session::Thread_creation_failed(); throw Cpu_session::Thread_creation_failed();
@ -72,7 +75,7 @@ void Thread_base::start()
_cpu_session->set_pager(_thread_cap, pager_cap); _cpu_session->set_pager(_thread_cap, pager_cap);
/* register initial IP and SP at core */ /* 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 * 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 * In contrast to the ordinary implementation, core's version does
* not split between allocation of memory and virtual memory management. * not split between allocation of memory and virtual memory management.
* Due to the missing availability of "real" dataspaces and capabilities * 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" * of a dataspace has no effect, but the attachment of the thereby "empty"
* dataspace is doing both: allocation and attachment. * dataspace is doing both: allocation and attachment.
*/ */
class Context_area_rm_session : public Rm_session class Stack_area_rm_session : public Rm_session
{ {
private: private:
@ -53,7 +53,7 @@ class Context_area_rm_session : public Rm_session
public: 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 */ Local_addr attach(Dataspace_capability ds_cap, /* ignored capability */
size_t size, off_t offset, 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(); Range_allocator *ra = platform_specific()->ram_alloc();
if (ra->alloc_aligned(size, &phys_base, if (ra->alloc_aligned(size, &phys_base,
get_page_size_log2()).is_error()) { 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; return (addr_t)0;
} }
@ -76,11 +76,11 @@ class Context_area_rm_session : public Rm_session
Dataspace_component *ds = new (&_ds_slab) Dataspace_component *ds = new (&_ds_slab)
Dataspace_component(size, 0, (addr_t)phys_base, CACHED, true, 0); Dataspace_component(size, 0, (addr_t)phys_base, CACHED, true, 0);
if (!ds) { if (!ds) {
PERR("dataspace for core context does not exist"); PERR("dataspace for core stack does not exist");
return (addr_t)0; 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; (addr_t)local_addr;
if (verbose) if (verbose)
@ -103,15 +103,14 @@ class Context_area_rm_session : public Rm_session
{ {
using Genode::addr_t; 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; 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)local_addr;
addr_t const thread_context = Native_config::context_virtual_size(); addr_t const stack = Native_config::stack_virtual_size();
addr_t const pages = ((detach & ~(thread_context - 1)) addr_t const pages = ((detach & ~(stack - 1)) + stack - detach)
+ thread_context >> get_page_size_log2();
- detach) >> get_page_size_log2();
unmap_local(detach, pages); 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: public:
@ -154,15 +153,15 @@ class Context_area_ram_session : public Ram_session
*/ */
namespace Genode { 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; 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; return &inst;
} }
} }

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