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 */
xml.node("start", [&] () {
gen_fs_rom_start_content(xml, "depot_rom", "cached_fs_rom", "depot",
cached_depot_rom_state.ram_quota,
cached_depot_rom_state.cap_quota); });
gen_fs_rom_start_content(xml, "cached_fs_rom", "depot",
cached_depot_rom_state); });
/* depot-ROM instance for mutable content (/depot/local/) */
xml.node("start", [&] () {
gen_fs_rom_start_content(xml, "dynamic_depot_rom", "fs_rom", "depot",
uncached_depot_rom_state.ram_quota,
uncached_depot_rom_state.cap_quota); });
gen_fs_rom_start_content(xml, "fs_rom", "depot",
uncached_depot_rom_state); });
xml.node("start", [&] () {
gen_depot_query_start_content(xml); });

View File

@ -47,10 +47,11 @@ struct Sculpt::Deploy
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 };
Depot_rom_state uncached_depot_rom_state { 8*1024*1024, 200 };
Child_state uncached_depot_rom_state {
"dynamic_depot_rom", Ram_quota{8*1024*1024}, Cap_quota{200} };
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 };
Child_state _runtime_view_state {
"runtime_view", Ram_quota{8*1024*1024}, Cap_quota{200} };
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) {
if (child.attribute_value("name", String<16>()) != "ram_fs")
return;
/* use binary OR (|), not logical OR (||), to always execute all elements */
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;
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", [&] () {
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);

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>
/* local includes */
#include "types.h"
#include <types.h>
#include <model/child_state.h>
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;
Ram_fs_state(Start_name const &name)
: Child_state(name, Ram_quota{1024*1024}, Cap_quota{300}) { }
};
#endif /* _MODEL__RAM_FS_STATE_H_ */

View File

@ -41,7 +41,8 @@ namespace Sculpt {
void gen_depot_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; };
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 &,
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 &,
Ram_quota, Cap_quota);
Child_state const &);
void gen_gpt_relabel_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>
void Sculpt::gen_fs_rom_start_content(Xml_generator &xml,
Start_name const &name,
Start_name const &binary,
Start_name const &server,
Ram_quota ram_quota,
Cap_quota cap_quota)
Child_state const &state)
{
gen_common_start_content(xml, name, cap_quota, ram_quota);
state.gen_start_node_content(xml);
gen_named_node(xml, "binary", binary);

View File

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

View File

@ -18,9 +18,11 @@
#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");

View File

@ -49,7 +49,7 @@ struct Sculpt::Storage : Storage_dialog::Action
Storage_devices _storage_devices { };
Ram_fs_state _ram_fs_state { };
Ram_fs_state _ram_fs_state { "ram_fs" };
Storage_target _sculpt_partition { };
@ -182,9 +182,7 @@ struct Sculpt::Storage : Storage_dialog::Action
void reset_ram_fs() override
{
_ram_fs_state.ram_quota = Ram_fs_state::initial_ram_quota();
_ram_fs_state.cap_quota = Ram_fs_state::initial_cap_quota();
_ram_fs_state.version.value++;
_ram_fs_state.trigger_restart();
dialog.reset_operation();
_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", [&] () {
xml.attribute("east", "yes");
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)); }); });
});
});