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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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