Facility for reinitializing Platform_env

The new function 'Platform_env::reload_parent_cap' triggers a reload
of the parent capability and its respective resources. It is needed
during the bootstrap of a new process forked from an existing Noux
process.
This commit is contained in:
Norman Feske 2012-02-15 19:14:37 +01:00
parent b6b05a032b
commit f3fcb5f56f
6 changed files with 114 additions and 33 deletions

View File

@ -1,6 +1,7 @@
SRC_CC = env.cc context_area.cc cap_sel_alloc.cc
SRC_CC = env.cc context_area.cc cap_sel_alloc.cc reload_parent_cap.cc
LIBS = ipc heap log_console lock
vpath env.cc $(BASE_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
vpath env.cc $(BASE_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env

View File

@ -1,7 +1,9 @@
SRC_CC = env.cc cap_sel_alloc.cc main_thread.cc context_area.cc
SRC_CC = env.cc cap_sel_alloc.cc main_thread.cc context_area.cc \
reload_parent_cap.cc
LIBS = ipc heap lock log_console
vpath env.cc $(BASE_DIR)/src/base/env
vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
vpath main_thread.cc $(REP_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath env.cc $(BASE_DIR)/src/base/env
vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
vpath main_thread.cc $(REP_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env

View File

@ -77,6 +77,9 @@ namespace Genode {
* \return 0 on success or negative error code
*/
int expand(size_t size, Range_allocator *alloc);
void reassign_resources(Ram_session *ram, Rm_session *rm) {
_ram_session = ram, _rm_session = rm; }
};
/*
@ -128,6 +131,12 @@ namespace Genode {
*/
int quota_limit(size_t new_quota_limit);
/**
* Re-assign RAM and RM sessions
*/
void reassign_resources(Ram_session *ram, Rm_session *rm) {
_ds_pool.reassign_resources(ram, rm); }
/*************************
** Allocator interface **

View File

@ -106,15 +106,28 @@ namespace Genode {
private:
Parent_client _parent_client;
Parent *_parent;
Ram_session_capability _ram_session_cap;
Expanding_ram_session_client _ram_session_client;
Cpu_session_client _cpu_session_client;
Expanding_rm_session_client _rm_session_client;
Pd_session_client _pd_session_client;
Heap _heap;
Parent_client _parent_client;
struct Resources
{
Ram_session_capability ram_cap;
Expanding_ram_session_client ram;
Cpu_session_client cpu;
Expanding_rm_session_client rm;
Pd_session_client pd;
Resources(Parent &parent)
:
ram_cap(static_cap_cast<Ram_session>(parent.session("Env::ram_session", ""))),
ram(ram_cap),
cpu(static_cap_cast<Cpu_session>(parent.session("Env::cpu_session", ""))),
rm(static_cap_cast<Rm_session>(parent.session("Env::rm_session", ""))),
pd(static_cap_cast<Pd_session>(parent.session("Env::pd_session", "")))
{ }
};
Resources _resources;
Heap _heap;
public:
@ -123,26 +136,37 @@ namespace Genode {
*/
Platform_env()
:
_parent_client(Genode::parent_cap()), _parent(&_parent_client),
_ram_session_cap(static_cap_cast<Ram_session>(parent()->session("Env::ram_session", ""))),
_ram_session_client(_ram_session_cap),
_cpu_session_client(static_cap_cast<Cpu_session>(parent()->session("Env::cpu_session", ""))),
_rm_session_client(static_cap_cast<Rm_session>(parent()->session("Env::rm_session", ""))),
_pd_session_client(static_cap_cast<Pd_session>(parent()->session("Env::pd_session", ""))),
_heap(ram_session(), rm_session())
_parent_client(Genode::parent_cap()),
_resources(_parent_client),
_heap(&_resources.ram, &_resources.rm)
{ }
/**
* Reload parent capability and reinitialize environment resources
*
* This function is solely used for implementing fork semantics.
* After forking a process, the new child process is executed
* within a copy of the address space of the forking process.
* Thereby, the new process inherits the original 'Platform_env'
* object of the forking process, which is meaningless in the
* context of the new process. By calling this function, the new
* process is able to reinitialize its 'Platform_env' with
* meaningful capabilities obtained via its updated parent
* capability.
*/
void reload_parent_cap();
/*******************
** Env interface **
*******************/
Parent *parent() { return _parent; }
Ram_session *ram_session() { return &_ram_session_client; }
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Cpu_session *cpu_session() { return &_cpu_session_client; }
Rm_session *rm_session() { return &_rm_session_client; }
Pd_session *pd_session() { return &_pd_session_client; }
Parent *parent() { return &_parent_client; }
Ram_session *ram_session() { return &_resources.ram; }
Ram_session_capability ram_session_cap() { return _resources.ram_cap; }
Cpu_session *cpu_session() { return &_resources.cpu; }
Rm_session *rm_session() { return &_resources.rm; }
Pd_session *pd_session() { return &_resources.pd; }
Allocator *heap() { return &_heap; }
};
}

View File

@ -1,5 +1,6 @@
SRC_CC = env.cc context_area.cc
SRC_CC = env.cc context_area.cc reload_parent_cap.cc
LIBS = ipc heap log_console lock
vpath env.cc $(REP_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath env.cc $(REP_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env

44
base/src/base/env/reload_parent_cap.cc vendored Normal file
View File

@ -0,0 +1,44 @@
/*
* \brief Environment reinitialization
* \author Norman Feske
* \date 2012-02-16
*/
/*
* Copyright (C) 2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/platform_env.h>
void Genode::Platform_env::reload_parent_cap()
{
/*
* This function is unused during the normal operation of Genode. It is
* relevant only for implementing fork semantics such as provided by the
* Noux execution environment.
*
* The function is called by the freshly created process right after the
* fork happened. During the fork, the Noux environment is expected to have
* updated the '_parent_cap' of the new process.
*
* The existing 'Platform_env' object contains capabilities that are
* meaningful for the forking process but not the new process. Before the
* the environment can be used, it must be reinitialized with the resources
* provided by the actual parent.
*/
_parent_client = Parent_client(Genode::parent_cap());
_resources = Resources(_parent_client);
/*
* Keep information about dynamically allocated memory but use the new
* resources as backing store. Note that the capabilites of the already
* allocated backing-store dataspaces are rendered meaningless. But this is
* no problem because they are used by the 'Heap' destructor only, which is
* never called for heap instance of 'Platform_env'.
*/
_heap.reassign_resources(&_resources.ram, &_resources.rm);
}