sculpt: increase runtime-view RAM/caps on demand

This patch unifies the handling of on-demand resource upgrades among
ram_fs and depot_rom, and applies the new pattern to the runtime view.
This way, runtime view becomes able to accommodate more complex
scenarios.
This commit is contained in:
Norman Feske 2018-09-03 15:39:28 +02:00
parent 50dcf40f24
commit 9c377906cf
11 changed files with 145 additions and 71 deletions

View File

@ -161,15 +161,13 @@ void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml) const
{ {
/* depot-ROM instance for regular (immutable) depot content */ /* depot-ROM instance for regular (immutable) depot content */
xml.node("start", [&] () { xml.node("start", [&] () {
gen_fs_rom_start_content(xml, "depot_rom", "cached_fs_rom", "depot", gen_fs_rom_start_content(xml, "cached_fs_rom", "depot",
cached_depot_rom_state.ram_quota, cached_depot_rom_state); });
cached_depot_rom_state.cap_quota); });
/* depot-ROM instance for mutable content (/depot/local/) */ /* depot-ROM instance for mutable content (/depot/local/) */
xml.node("start", [&] () { xml.node("start", [&] () {
gen_fs_rom_start_content(xml, "dynamic_depot_rom", "fs_rom", "depot", gen_fs_rom_start_content(xml, "fs_rom", "depot",
uncached_depot_rom_state.ram_quota, uncached_depot_rom_state); });
uncached_depot_rom_state.cap_quota); });
xml.node("start", [&] () { xml.node("start", [&] () {
gen_depot_query_start_content(xml); }); gen_depot_query_start_content(xml); });

View File

@ -47,10 +47,11 @@ struct Sculpt::Deploy
struct Query_version { unsigned value; } _query_version { 0 }; struct Query_version { unsigned value; } _query_version { 0 };
struct Depot_rom_state { Ram_quota ram_quota; Cap_quota cap_quota; }; Child_state cached_depot_rom_state {
"depot_rom", Ram_quota{24*1024*1024}, Cap_quota{200} };
Depot_rom_state cached_depot_rom_state { 24*1024*1024, 200 }; Child_state uncached_depot_rom_state {
Depot_rom_state uncached_depot_rom_state { 8*1024*1024, 200 }; "dynamic_depot_rom", Ram_quota{8*1024*1024}, Cap_quota{200} };
Attached_rom_dataspace _manual_deploy_rom { _env, "config -> deploy" }; Attached_rom_dataspace _manual_deploy_rom { _env, "config -> deploy" };

View File

@ -381,6 +381,9 @@ struct Sculpt::Main : Input_event_handler,
Graph _graph { _env, _runtime_state, _storage._sculpt_partition }; Graph _graph { _env, _runtime_state, _storage._sculpt_partition };
Child_state _runtime_view_state {
"runtime_view", Ram_quota{8*1024*1024}, Cap_quota{200} };
Main(Env &env) : _env(env) Main(Env &env) : _env(env)
{ {
@ -771,46 +774,18 @@ void Sculpt::Main::_handle_runtime_state()
} }
} }
/* upgrade ram_fs quota on demand */ /* upgrade RAM and cap quota on demand */
state.for_each_sub_node("child", [&] (Xml_node child) { state.for_each_sub_node("child", [&] (Xml_node child) {
if (child.attribute_value("name", String<16>()) != "ram_fs") /* use binary OR (|), not logical OR (||), to always execute all elements */
return; if (_storage._ram_fs_state.apply_child_state_report(child)
| _deploy.cached_depot_rom_state.apply_child_state_report(child)
| _deploy.uncached_depot_rom_state.apply_child_state_report(child)
| _runtime_view_state.apply_child_state_report(child)) {
if (child.has_sub_node("ram") && child.sub_node("ram").has_attribute("requested")) {
_storage._ram_fs_state.ram_quota.value *= 2;
reconfigure_runtime = true; reconfigure_runtime = true;
generate_dialog(); generate_dialog();
} }
if (child.has_sub_node("caps") && child.sub_node("caps").has_attribute("requested")) {
_storage._ram_fs_state.cap_quota.value += 100;
reconfigure_runtime = true;
generate_dialog();
}
});
/* upgrade depot_rom quota on demand */
state.for_each_sub_node("child", [&] (Xml_node child) {
auto upgrade_depot_rom = [&] (Deploy::Depot_rom_state &state, Start_name const &name)
{
if (child.attribute_value("name", Start_name()) != name)
return;
if (child.has_sub_node("ram") && child.sub_node("ram").has_attribute("requested")) {
state.ram_quota.value *= 2;
reconfigure_runtime = true;
}
if (child.has_sub_node("caps") && child.sub_node("caps").has_attribute("requested")) {
state.cap_quota.value += 100;
reconfigure_runtime = true;
}
};
upgrade_depot_rom(_deploy.cached_depot_rom_state, "depot_rom");
upgrade_depot_rom(_deploy.uncached_depot_rom_state, "dynamic_depot_rom");
}); });
/* /*
@ -863,7 +838,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
}); });
xml.node("start", [&] () { xml.node("start", [&] () {
gen_runtime_view_start_content(xml, _gui.font_size()); }); gen_runtime_view_start_content(xml, _runtime_view_state, _gui.font_size()); });
_storage.gen_runtime_start_nodes(xml); _storage.gen_runtime_start_nodes(xml);

View File

@ -0,0 +1,107 @@
/*
* \brief Runtime state of a child hosted in the runtime subsystem
* \author Norman Feske
* \date 2018-09-03
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _MODEL__CHILD_STATE_H_
#define _MODEL__CHILD_STATE_H_
/* Genode includes */
#include <util/xml_node.h>
/* local includes */
#include "types.h"
namespace Sculpt { struct Child_state; }
struct Sculpt::Child_state : Noncopyable
{
private:
Start_name const _name;
Ram_quota const _initial_ram_quota;
Cap_quota const _initial_cap_quota;
Ram_quota _ram_quota = _initial_ram_quota;
Cap_quota _cap_quota = _initial_cap_quota;
struct Version { unsigned value; } _version { 0 };
public:
/**
* Constructor
*
* \param ram_quota initial RAM quota
* \param cap_quota initial capability quota
*/
Child_state(Start_name const &name,
Ram_quota ram_quota, Cap_quota cap_quota)
:
_name(name),
_initial_ram_quota(ram_quota), _initial_cap_quota(cap_quota)
{ }
void trigger_restart()
{
_version.value++;
_ram_quota = _initial_ram_quota;
_cap_quota = _initial_cap_quota;
}
void gen_start_node_content(Xml_generator &xml) const
{
xml.attribute("name", _name);
if (_version.value)
xml.attribute("version", _version.value);
xml.attribute("caps", _cap_quota.value);
gen_named_node(xml, "resource", "RAM", [&] () {
Number_of_bytes const bytes(_ram_quota.value);
xml.attribute("quantum", String<64>(bytes)); });
}
/**
* Adapt runtime state information to the child
*
* This method responds to RAM and cap-resource requests by increasing
* the resource quotas as needed.
*
* \param child child node of the runtime'r state report
* \return true if runtime must be reconfigured so that the changes
* can take effect
*/
bool apply_child_state_report(Xml_node child)
{
bool result = false;
if (child.attribute_value("name", Start_name()) != _name)
return false;
if (child.has_sub_node("ram") && child.sub_node("ram").has_attribute("requested")) {
_ram_quota.value *= 2;
result = true;
}
if (child.has_sub_node("caps") && child.sub_node("caps").has_attribute("requested")) {
_cap_quota.value += 100;
result = true;
}
return result;
}
Ram_quota ram_quota() const { return _ram_quota; }
};
#endif /* _MODEL__CHILD_STATE_H_ */

View File

@ -18,21 +18,17 @@
#include <util/xml_node.h> #include <util/xml_node.h>
/* local includes */ /* local includes */
#include "types.h" #include <types.h>
#include <model/child_state.h>
namespace Sculpt { struct Ram_fs_state; } namespace Sculpt { struct Ram_fs_state; }
struct Sculpt::Ram_fs_state : Noncopyable struct Sculpt::Ram_fs_state : Child_state
{ {
static Ram_quota initial_ram_quota() { return Ram_quota{1024*1024}; }
static Cap_quota initial_cap_quota() { return Cap_quota{300}; }
Ram_quota ram_quota = initial_ram_quota();
Cap_quota cap_quota = initial_cap_quota();
struct Version { unsigned value; } version { 0 };
bool inspected = false; bool inspected = false;
Ram_fs_state(Start_name const &name)
: Child_state(name, Ram_quota{1024*1024}, Cap_quota{300}) { }
}; };
#endif /* _MODEL__RAM_FS_STATE_H_ */ #endif /* _MODEL__RAM_FS_STATE_H_ */

View File

@ -41,7 +41,8 @@ namespace Sculpt {
void gen_depot_query_start_content(Xml_generator &); void gen_depot_query_start_content(Xml_generator &);
void gen_launcher_query_start_content(Xml_generator &); void gen_launcher_query_start_content(Xml_generator &);
void gen_runtime_view_start_content(Xml_generator &, float font_size); void gen_runtime_view_start_content(Xml_generator &, Child_state const &,
float font_size);
struct File_browser_version { unsigned value; }; struct File_browser_version { unsigned value; };
void gen_file_browser(Xml_generator &, Storage_devices const &, void gen_file_browser(Xml_generator &, Storage_devices const &,
@ -52,9 +53,9 @@ namespace Sculpt {
void gen_fs_start_content(Xml_generator &, Storage_target const &, void gen_fs_start_content(Xml_generator &, Storage_target const &,
File_system::Type); File_system::Type);
void gen_fs_rom_start_content(Xml_generator &, Start_name const &, void gen_fs_rom_start_content(Xml_generator &,
Start_name const &, Start_name const &, Start_name const &, Start_name const &,
Ram_quota, Cap_quota); Child_state const &);
void gen_gpt_relabel_start_content(Xml_generator &, Storage_device const &); void gen_gpt_relabel_start_content(Xml_generator &, Storage_device const &);
void gen_gpt_expand_start_content (Xml_generator &, Storage_device const &); void gen_gpt_expand_start_content (Xml_generator &, Storage_device const &);

View File

@ -14,13 +14,11 @@
#include <runtime.h> #include <runtime.h>
void Sculpt::gen_fs_rom_start_content(Xml_generator &xml, void Sculpt::gen_fs_rom_start_content(Xml_generator &xml,
Start_name const &name,
Start_name const &binary, Start_name const &binary,
Start_name const &server, Start_name const &server,
Ram_quota ram_quota, Child_state const &state)
Cap_quota cap_quota)
{ {
gen_common_start_content(xml, name, cap_quota, ram_quota); state.gen_start_node_content(xml);
gen_named_node(xml, "binary", binary); gen_named_node(xml, "binary", binary);

View File

@ -16,9 +16,7 @@
void Sculpt::gen_ram_fs_start_content(Xml_generator &xml, void Sculpt::gen_ram_fs_start_content(Xml_generator &xml,
Ram_fs_state const &state) Ram_fs_state const &state)
{ {
xml.attribute("version", state.version.value); state.gen_start_node_content(xml);
gen_common_start_content(xml, "ram_fs", state.cap_quota, state.ram_quota);
gen_provides<::File_system::Session>(xml); gen_provides<::File_system::Session>(xml);

View File

@ -18,9 +18,11 @@
#include <runtime.h> #include <runtime.h>
void Sculpt::gen_runtime_view_start_content(Xml_generator &xml, float font_size) void Sculpt::gen_runtime_view_start_content(Xml_generator &xml,
Child_state const &state,
float font_size)
{ {
gen_common_start_content(xml, "runtime_view", Cap_quota{200}, Ram_quota{9*1024*1024}); state.gen_start_node_content(xml);
gen_named_node(xml, "binary", "menu_view"); gen_named_node(xml, "binary", "menu_view");

View File

@ -49,7 +49,7 @@ struct Sculpt::Storage : Storage_dialog::Action
Storage_devices _storage_devices { }; Storage_devices _storage_devices { };
Ram_fs_state _ram_fs_state { }; Ram_fs_state _ram_fs_state { "ram_fs" };
Storage_target _sculpt_partition { }; Storage_target _sculpt_partition { };
@ -182,9 +182,7 @@ struct Sculpt::Storage : Storage_dialog::Action
void reset_ram_fs() override void reset_ram_fs() override
{ {
_ram_fs_state.ram_quota = Ram_fs_state::initial_ram_quota(); _ram_fs_state.trigger_restart();
_ram_fs_state.cap_quota = Ram_fs_state::initial_cap_quota();
_ram_fs_state.version.value++;
dialog.reset_operation(); dialog.reset_operation();
_runtime_config_generator.generate_runtime_config(); _runtime_config_generator.generate_runtime_config();

View File

@ -358,7 +358,7 @@ void Sculpt::Storage_dialog::_gen_ram_fs(Xml_generator &xml) const
gen_named_node(xml, "float", "capacity", [&] () { gen_named_node(xml, "float", "capacity", [&] () {
xml.attribute("east", "yes"); xml.attribute("east", "yes");
xml.node("label", [&] () { xml.node("label", [&] () {
Capacity const capacity { _ram_fs_state.ram_quota.value }; Capacity const capacity { _ram_fs_state.ram_quota().value };
xml.attribute("text", String<64>(capacity)); }); }); xml.attribute("text", String<64>(capacity)); }); });
}); });
}); });