diff --git a/repos/ealanos/include/sandbox/sandbox.h b/repos/ealanos/include/sandbox/sandbox.h
index b9fd6bf4b3..1502d5b1ce 100644
--- a/repos/ealanos/include/sandbox/sandbox.h
+++ b/repos/ealanos/include/sandbox/sandbox.h
@@ -22,7 +22,9 @@
#include
namespace Genode { class Sandbox; }
-
+namespace Sandbox {
+ class Child;
+}
class Genode::Sandbox : Noncopyable
{
@@ -43,6 +45,7 @@ class Genode::Sandbox : Noncopyable
struct State_handler : Interface
{
virtual void handle_sandbox_state() = 0;
+ virtual void handle_child_state(::Sandbox::Child &child) = 0;
};
/**
@@ -108,8 +111,9 @@ class Genode::Sandbox : Noncopyable
* \throw Xml_generator::Buffer_exceeded
*/
void generate_state_report(Xml_generator &) const;
-};
+ void update(::Sandbox::Child &child);
+};
class Genode::Sandbox::Local_service_base : public Service
{
diff --git a/repos/ealanos/src/hoitaja/main.cc b/repos/ealanos/src/hoitaja/main.cc
index 29924e0a8a..03d6045a9c 100644
--- a/repos/ealanos/src/hoitaja/main.cc
+++ b/repos/ealanos/src/hoitaja/main.cc
@@ -18,7 +18,7 @@
#include
#include
#include
-
+#include
namespace Init {
using namespace Genode;
@@ -27,11 +27,11 @@ namespace Init {
}
-struct Init::Main : Sandbox::State_handler
+struct Init::Main : Genode::Sandbox::State_handler
{
Env &_env;
- Sandbox _sandbox { _env, *this };
+ Genode::Sandbox _sandbox { _env, *this };
Attached_rom_dataspace _config { _env, "config" };
@@ -96,6 +96,16 @@ struct Init::Main : Sandbox::State_handler
}
}
+ void handle_child_state(::Sandbox::Child &child) override {
+ try {
+ Genode::log("Updating sandbox state");
+ _sandbox.update(child);
+ } catch (Genode::Quota_guard::Limit_exceeded) {
+ Genode::log("Caps exceeded while handling child state");
+ _env.parent().exit(1);
+ }
+ }
+
Main(Env &env) : _env(env)
{
_config.sigh(_config_handler);
diff --git a/repos/ealanos/src/hoitaja/target.mk b/repos/ealanos/src/hoitaja/target.mk
index d8089f8834..c94e0c088f 100644
--- a/repos/ealanos/src/hoitaja/target.mk
+++ b/repos/ealanos/src/hoitaja/target.mk
@@ -7,6 +7,7 @@ CONFIG_XSD = config.xsd
# statically link sandbox library to avoid dependency from sandbox.lib.so
SRC_CC += library.cc child.cc server.cc config_model.cc
+INC_DIR += $(REP_DIR)/include
INC_DIR += $(REP_DIR)/src/lib/sandbox
vpath %.cc $(REP_DIR)/src/lib/sandbox
diff --git a/repos/ealanos/src/lib/sandbox/child.cc b/repos/ealanos/src/lib/sandbox/child.cc
index a86a0ef417..9de8c8f83f 100644
--- a/repos/ealanos/src/lib/sandbox/child.cc
+++ b/repos/ealanos/src/lib/sandbox/child.cc
@@ -755,10 +755,12 @@ Sandbox::Child::Child(Env &env,
Registry &child_services,
Registry &local_services,
Pd_intrinsics &pd_intrinsics,
- Ealan::Habitat_connection &habitat)
+ Ealan::Habitat_connection &habitat,
+ Genode::Sandbox::State_handler &habitat_handler)
:
_env(env), _alloc(alloc), _verbose(verbose), _id(id),
_report_update_trigger(report_update_trigger),
+ _habitat_handler(habitat_handler),
_list_element(this),
_start_node(_alloc, start_node),
_default_route_accessor(default_route_accessor),
@@ -776,8 +778,7 @@ Sandbox::Child::Child(Env &env,
_child_services(child_services),
_local_services(local_services),
_session_requester(_env.ep().rpc_ep(), _env.ram(), _env.rm()),
- _habitat(habitat)
-{
+ _habitat(habitat){
log("Creating new cell <", _unique_name, ">");
if (_verbose.enabled()) {
log("child \"", _unique_name, "\"");
diff --git a/repos/ealanos/src/lib/sandbox/child.h b/repos/ealanos/src/lib/sandbox/child.h
index 54e45f5662..70084ed7dd 100644
--- a/repos/ealanos/src/lib/sandbox/child.h
+++ b/repos/ealanos/src/lib/sandbox/child.h
@@ -35,9 +35,11 @@
#include
#include
#include
+#include
/* EalánOS includes */
#include
+#include |
namespace Sandbox { class Child; }
@@ -105,6 +107,46 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
{
pd_intrinsics.with_intrinsics(cap, pd, Pd_intrinsics::With_intrinsics::Fn { fn });
}
+
+ /**
+ * Resources assigned to the child
+ */
+ struct Resources
+ {
+ long prio_levels_log2;
+ long priority;
+ Affinity affinity;
+ Ram_quota assigned_ram_quota;
+ Cap_quota assigned_cap_quota;
+ Cpu_quota assigned_cpu_quota;
+
+ Ram_quota effective_ram_quota() const
+ {
+ return Genode::Child::effective_quota(assigned_ram_quota);
+ }
+
+ Cap_quota effective_cap_quota() const
+ {
+ /* capabilities consumed by 'Genode::Child' */
+ Cap_quota const effective =
+ Genode::Child::effective_quota(assigned_cap_quota);
+
+ /* capabilities additionally consumed by init */
+ enum {
+ STATIC_COSTS = 1 /* possible heap backing-store
+ allocation for session object */
+ + 1 /* buffered XML start node */
+ + 2 /* dynamic ROM for config */
+ + 2 /* dynamic ROM for session requester */
+ };
+
+ if (effective.value < STATIC_COSTS)
+ return Cap_quota{0};
+
+ return Cap_quota{effective.value - STATIC_COSTS};
+ }
+ };
+
private:
@@ -149,6 +191,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Report_update_trigger &_report_update_trigger;
+ Genode::Sandbox::State_handler &_habitat_handler;
+
List_element _list_element;
Reconstructible _start_node;
@@ -237,45 +281,6 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
return _heartbeat_enabled && (_state == State::ALIVE);
}
- /**
- * Resources assigned to the child
- */
- struct Resources
- {
- long prio_levels_log2;
- long priority;
- Affinity affinity;
- Ram_quota assigned_ram_quota;
- Cap_quota assigned_cap_quota;
- Cpu_quota assigned_cpu_quota;
-
- Ram_quota effective_ram_quota() const
- {
- return Genode::Child::effective_quota(assigned_ram_quota);
- }
-
- Cap_quota effective_cap_quota() const
- {
- /* capabilities consumed by 'Genode::Child' */
- Cap_quota const effective =
- Genode::Child::effective_quota(assigned_cap_quota);
-
- /* capabilities additionally consumed by init */
- enum {
- STATIC_COSTS = 1 /* possible heap backing-store
- allocation for session object */
- + 1 /* buffered XML start node */
- + 2 /* dynamic ROM for config */
- + 2 /* dynamic ROM for session requester */
- };
-
- if (effective.value < STATIC_COSTS)
- return Cap_quota{0};
-
- return Cap_quota{effective.value - STATIC_COSTS};
- }
- };
-
static
Resources _resources_from_start_node(Xml_node start_node, Prio_levels prio_levels,
Affinity::Space const &affinity_space, Affinity::Location const &location,
@@ -421,6 +426,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Genode::Child _child { _env.rm(), _env.ep().rpc_ep(), *this };
+ Ealan::Cell_capability _cell_cap { };
+
struct Pd_accessor : Routed_service::Pd_accessor
{
Genode::Child &_child;
@@ -528,6 +535,7 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
bool _exited { false };
int _exit_value { -1 };
+
/**
* Return true if it's safe to call the PD for requesting resource
* information
@@ -606,7 +614,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
Registry &child_services,
Registry &local_services,
Pd_intrinsics &pd_intrinsics,
- Ealan::Habitat_connection &habitat);
+ Ealan::Habitat_connection &habitat,
+ Genode::Sandbox::State_handler &habitat_handler);
virtual ~Child();
@@ -640,8 +649,9 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
_child.initiate_env_sessions();
if (_child.active()) {
- _habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast(_priority));
- _state = State::ALIVE;
+ _cell_cap = _habitat.create_cell(_child.pd_session_cap(), _resources.affinity, static_cast(_priority), Genode::Session_label(_unique_name));
+ Genode::log("Created new cell ", _unique_name, " ", _cell_cap);
+ _state = State::ALIVE;
} else
_uncertain_dependencies = true;
}
@@ -668,6 +678,8 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
bool restart_scheduled() const { return _state == State::RESTART_SCHEDULED; }
bool stuck() const { return _state == State::STUCK; }
+
+ bool exited() { return _exited; }
bool env_sessions_closed() const { return _child.env_sessions_closed(); }
@@ -726,19 +738,16 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
struct Resources &resources() { return _resources; }
- void update_affinity(Genode::Affinity affinity) {
- //Genode::log("Updating affinity to ", affinity.location(), " in space ", affinity.space());
+ void update(Genode::Affinity affinity) {
+ Genode::log("Updating affinity to ", affinity.location(), " in space ", affinity.space());
_resources.affinity = affinity;
//Genode::log("Moving CPU session ", _env.cpu_session_cap());
if (_child.active()) {
- }
- }
-
- void shrink_cores(Genode::Affinity::Location &cores) {
- }
-
- void grow_cores(Genode::Affinity::Location &cores) {
- }
+ Ealan::Cell_client cell(_cell_cap);
+ Genode::log("Updating cell ", _cell_cap);
+ cell.update(affinity);
+ }
+ }
bool is_brick() { return false; }
@@ -800,6 +809,9 @@ class Sandbox::Child : Child_policy, Routed_service::Wakeup
* printed by the default implementation of 'Child_policy::exit'.
*/
Child_policy::exit(exit_value);
+
+ Genode::log("Notifying Hoitaja");
+ _habitat_handler.handle_child_state(*this);
}
void session_state_changed() override
diff --git a/repos/ealanos/src/lib/sandbox/core_allocator.h b/repos/ealanos/src/lib/sandbox/core_allocator.h
index 0ecb7f7fcf..564ab8db2e 100644
--- a/repos/ealanos/src/lib/sandbox/core_allocator.h
+++ b/repos/ealanos/src/lib/sandbox/core_allocator.h
@@ -86,7 +86,7 @@ class Hoitaja::Core_allocator
void update(::Sandbox::Child &cell, int *xpos, int *lower_limit) {
if (cell.abandoned())
return;
- /*::Sandbox::Child::Resources resources = cell.resources();
+ ::Sandbox::Child::Resources resources = cell.resources();
long priority = (resources.priority == 0)? 1 : resources.priority;
unsigned int cores_share = _calculate_resource_share(priority);
@@ -100,13 +100,14 @@ class Hoitaja::Core_allocator
Genode::Affinity::Location location(*xpos - cores_share, resources.affinity.location().ypos(), cores_share, resources.affinity.location().height());
- if (resources.affinity.location() != location) { // Only update, if location has actually changed
+ /*if (resources.affinity.location() != location) { // Only update, if location has actually changed
cell.update_affinity(Genode::Affinity(resources.affinity.space(), location));
}
if (location.width() > resources.affinity.location().width()) {
cell.grow_cores(location);
- }
+ }*/
+
*xpos = location.xpos();
// TODO: Update affinity of existing sessions for cell
@@ -114,8 +115,9 @@ class Hoitaja::Core_allocator
if (cores_to_reclaim > 0) {
log("Need to reclaim ", cores_to_reclaim, " cores from ", cell.name());
- cell.shrink_cores(location);
- }*/
+ }
+
+ cell.update(Genode::Affinity(resources.affinity.space(), location));
}
diff --git a/repos/ealanos/src/lib/sandbox/library.cc b/repos/ealanos/src/lib/sandbox/library.cc
index 422ddeef42..f71a641de9 100644
--- a/repos/ealanos/src/lib/sandbox/library.cc
+++ b/repos/ealanos/src/lib/sandbox/library.cc
@@ -79,6 +79,8 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
Constructible _affinity_space { };
Preservation _preservation { };
+ State_handler &_habitat_handler;
+
Affinity::Space _effective_affinity_space() const
{
return _affinity_space.constructed() ? *_affinity_space
@@ -289,7 +291,7 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
State_handler &state_handler, Pd_intrinsics &pd_intrinsics)
:
_env(env), _heap(heap), _core_allocator(), _pd_intrinsics(pd_intrinsics),
- _local_services(local_services), _state_reporter(_env, *this, state_handler)
+ _local_services(local_services), _habitat_handler(state_handler), _state_reporter(_env, *this, state_handler)
{ }
Library(Env &env, Heap &heap, Registry &local_services,
@@ -304,8 +306,18 @@ struct Genode::Sandbox::Library : ::Sandbox::State_reporter::Producer,
{
_state_reporter.generate(xml);
}
-};
+ void maintain_cells();
+
+ void update(Child &child) {
+ if (child.exited()) {
+ _children.remove(&child);
+ _core_allocator->free_cores_from_cell(child);
+ Genode::log("Starting new maintenance cycle");
+ maintain_cells();
+ }
+ }
+};
void Genode::Sandbox::Library::_destroy_abandoned_parent_services()
{
@@ -400,9 +412,11 @@ bool Genode::Sandbox::Library::ready_to_create_child(Start_model::Name const
start_node, *this, *this, _children, *this, *this, *this, *this,
_prio_levels, _effective_affinity_space(), allocation,
_parent_services, _child_services, _local_services,
- _pd_intrinsics, *_habitat);
+ _pd_intrinsics, *_habitat, _habitat_handler);
_children.insert(&child);
+ maintain_cells();
+
_avail_cpu.percent -= min(_avail_cpu.percent, child.cpu_quota().percent);
if (start_node.has_sub_node("provides"))
@@ -537,6 +551,16 @@ void Genode::Sandbox::Library::apply_config(Xml_node const &config)
_state_reporter.trigger_immediate_report_update();
}
+void Genode::Sandbox::Library::maintain_cells()
+{
+ int xpos = _affinity_space->total();
+ int lower_limit = _affinity_space->total() - _core_allocator->cores_available();
+ _children.for_each_child([&](Child &child)
+ {
+ log(child.name(), " ram: ", child.ram_quota());
+ if (!(child.is_brick()))
+ _core_allocator->update(child, &xpos, &lower_limit); });
+}
/*********************************
** Sandbox::Local_service_base **
@@ -682,6 +706,10 @@ void Genode::Sandbox::generate_state_report(Xml_generator &xml) const
_library.generate_state_report(xml);
}
+void Genode::Sandbox::update(::Sandbox::Child &child)
+{
+ _library.update(child);
+}
Genode::Sandbox::Sandbox(Env &env, State_handler &state_handler, Pd_intrinsics &pd_intrinsics)
:
|