sculpt: introduce runtime priorities

This patch adds 4 priority levels to the runtime subsystem. The highest
priority is used for components that are critical for the operation of
Sculpt, in particular the Leitzentrale GUI. All regularly deployed
components are assigned the lowest priority by default.

With priorities available in the runtime subsystem, this patch flattens
the priority levels at the top-level init to only two levels and
overlays the priority bands of the drivers, leitzentrale, and runtime
subsystems into one priority band. This has three benenfits:

- This change prevents the starvation of the Leitzentrale GUI from a
  spinning high-priority driver (issue #3997).

- The change will also ease the hosting of latency-critical components
  in the runtime subsystem that are prioritized higher than regular
  components, the storage stack, and the network stack.

- The Leitzentrale GUI remains always perfectly responsive regardless
  of the workloads deployed from packages. In the previous version,
  the runtime graph was sometimes stuttering on high system load.

Issue #4045
This commit is contained in:
Norman Feske 2021-03-09 18:18:14 +01:00
parent 7bbd050f25
commit 8ecc258d3f
28 changed files with 191 additions and 81 deletions

View File

@ -1,4 +1,4 @@
<config prio_levels="2"> <config>
<parent-provides> <parent-provides>
<service name="ROM"/> <service name="ROM"/>
@ -79,7 +79,7 @@
</route> </route>
</start> </start>
<start name="acpi_drv" caps="350" priority="-1"> <start name="acpi_drv" caps="350">
<resource name="RAM" quantum="4M"/> <resource name="RAM" quantum="4M"/>
<route> <route>
<service name="Report" label="acpi"> <child name="report_rom"/> </service> <service name="Report" label="acpi"> <child name="report_rom"/> </service>
@ -131,7 +131,7 @@
</config> </config>
</start> </start>
<start name="usb_drv" caps="200" priority="-1"> <start name="usb_drv" caps="200">
<binary name="x86_pc_usb_host_drv"/> <binary name="x86_pc_usb_host_drv"/>
<resource name="RAM" quantum="16M"/> <resource name="RAM" quantum="16M"/>
<provides> <service name="Usb"/> </provides> <provides> <service name="Usb"/> </provides>
@ -150,7 +150,7 @@
</route> </route>
</start> </start>
<start name="usb_hid_drv" caps="140" priority="-1"> <start name="usb_hid_drv" caps="140">
<resource name="RAM" quantum="11M"/> <resource name="RAM" quantum="11M"/>
<config use_report="yes" capslock_led="rom" numlock_led="rom"/> <config use_report="yes" capslock_led="rom" numlock_led="rom"/>
<route> <route>
@ -168,7 +168,7 @@
</route> </route>
</start> </start>
<start name="ps2_drv" priority="0"> <start name="ps2_drv">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<config capslock_led="rom" numlock_led="rom"/> <config capslock_led="rom" numlock_led="rom"/>
<route> <route>
@ -184,7 +184,7 @@
</route> </route>
</start> </start>
<start name="rtc_drv" priority="-1"> <start name="rtc_drv">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Rtc"/> </provides> <provides> <service name="Rtc"/> </provides>
<route> <route>
@ -198,7 +198,7 @@
</start> </start>
<!-- toggle key mappings depending on the numlock state --> <!-- toggle key mappings depending on the numlock state -->
<start name="numlock_remap_rom" priority="-1"> <start name="numlock_remap_rom">
<binary name="rom_filter"/> <binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="ROM"/> </provides> <provides> <service name="ROM"/> </provides>
@ -209,7 +209,7 @@
</route> </route>
</start> </start>
<start name="event_filter" caps="90" priority="-1"> <start name="event_filter" caps="90">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides> <service name="Event"/> </provides> <provides> <service name="Event"/> </provides>
<route> <route>
@ -225,7 +225,7 @@
</route> </route>
</start> </start>
<start name="driver_manager" priority="-1"> <start name="driver_manager">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<route> <route>
<service name="Report" label="init.config"> <child name="report_rom"/> </service> <service name="Report" label="init.config"> <child name="report_rom"/> </service>
@ -243,7 +243,7 @@
</route> </route>
</start> </start>
<start name="dynamic" caps="1400" priority="0"> <start name="dynamic" caps="1400">
<binary name="init"/> <binary name="init"/>
<resource name="RAM" quantum="1G"/> <resource name="RAM" quantum="1G"/>
<provides> <provides>

View File

@ -25,7 +25,7 @@ proc nic_drv {} {
} }
install_config { install_config {
<config prio_levels="4"> <!-- set prio_levels to 4 --> <config prio_levels="2">
<parent-provides> <parent-provides>
<service name="ROM"/> <service name="ROM"/>
<service name="IRQ"/> <service name="IRQ"/>
@ -49,13 +49,13 @@ install_config {
<resource name="RAM" preserve="2M"/> <resource name="RAM" preserve="2M"/>
<start name="timer"> <start name="timer" priority="0">
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<resource name="CPU" quantum="10"/> <resource name="CPU" quantum="10"/>
<provides><service name="Timer"/></provides> <provides><service name="Timer"/></provides>
</start> </start>
<start name="report_rom"> <start name="report_rom" priority="0">
<binary name="report_rom"/> <binary name="report_rom"/>
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides> <provides> <service name="Report"/> <service name="ROM"/> </provides>
@ -81,14 +81,14 @@ install_config {
</config> </config>
</start> </start>
<start name="report_logger" priority="-3"> <start name="report_logger" priority="0">
<binary name="report_rom"/> <binary name="report_rom"/>
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides> <provides> <service name="Report"/> <service name="ROM"/> </provides>
<config verbose="yes"/> <config verbose="yes"/>
</start> </start>
<start name="config_fs" caps="200"> <start name="config_fs" caps="200" priority="0">
<binary name="vfs"/> <binary name="vfs"/>
<resource name="RAM" quantum="12M"/> <resource name="RAM" quantum="12M"/>
<provides> <service name="File_system"/> </provides> <provides> <service name="File_system"/> </provides>
@ -272,7 +272,7 @@ install_config {
</provides> </provides>
</start> </start>
<start name="nitpicker" caps="1000"> <start name="nitpicker" caps="1000" priority="0">
<resource name="RAM" quantum="6M"/> <resource name="RAM" quantum="6M"/>
<provides> <provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/> <service name="Gui"/> <service name="Capture"/> <service name="Event"/>
@ -376,7 +376,7 @@ install_config {
</route> </route>
</start> </start>
<start name="leitzentrale_config" priority="-2"> <start name="leitzentrale_config" priority="-1">
<binary name="rom_filter"/> <binary name="rom_filter"/>
<resource name="RAM" quantum="1M"/> <resource name="RAM" quantum="1M"/>
<provides><service name="ROM"/></provides> <provides><service name="ROM"/></provides>
@ -388,7 +388,7 @@ install_config {
</route> </route>
</start> </start>
<start name="clipboard" priority="-2"> <start name="clipboard" priority="-1">
<resource name="RAM" quantum="2M"/> <resource name="RAM" quantum="2M"/>
<provides> <provides>
<service name="ROM"/> <service name="Report"/> <service name="ROM"/> <service name="Report"/>
@ -401,7 +401,7 @@ install_config {
</route> </route>
</start> </start>
<start name="leitzentrale" caps="2350" priority="-2"> <start name="leitzentrale" caps="2350" priority="-1">
<binary name="init"/> <binary name="init"/>
<resource name="RAM" quantum="130M"/> <resource name="RAM" quantum="130M"/>
<affinity xpos="1" width="1"/> <!-- decouple leitzentrale from boot CPU --> <affinity xpos="1" width="1"/> <!-- decouple leitzentrale from boot CPU -->
@ -438,7 +438,7 @@ install_config {
</route> </route>
</start> </start>
<start name="runtime" caps="50000" priority="-3"> <start name="runtime" caps="50000" priority="-1">
<binary name="init"/> <binary name="init"/>
<resource name="RAM" quantum="32G"/> <resource name="RAM" quantum="32G"/>
<resource name="CPU" quantum="40"/> <resource name="CPU" quantum="40"/>

View File

@ -37,6 +37,16 @@ class Depot_deploy::Child : public List_model<Child>::Element
typedef String<32> Depot_rom_server; typedef String<32> Depot_rom_server;
typedef String<100> Launcher_name; typedef String<100> Launcher_name;
struct Prio_levels
{
unsigned value;
int min_priority() const
{
return (value > 0) ? -(int)(value - 1) : 0;
}
};
private: private:
Allocator &_alloc; Allocator &_alloc;
@ -296,6 +306,7 @@ class Depot_deploy::Child : public List_model<Child>::Element
* is assumed to be mutable * is assumed to be mutable
*/ */
inline void gen_start_node(Xml_generator &, Xml_node common, inline void gen_start_node(Xml_generator &, Xml_node common,
Prio_levels prio_levels,
Depot_rom_server const &cached_depot_rom, Depot_rom_server const &cached_depot_rom,
Depot_rom_server const &uncached_depot_rom) const; Depot_rom_server const &uncached_depot_rom) const;
@ -317,6 +328,7 @@ class Depot_deploy::Child : public List_model<Child>::Element
void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common, void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
Prio_levels prio_levels,
Depot_rom_server const &cached_depot_rom, Depot_rom_server const &cached_depot_rom,
Depot_rom_server const &uncached_depot_rom) const Depot_rom_server const &uncached_depot_rom) const
{ {
@ -331,27 +343,44 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
return; return;
} }
Xml_node const launcher_xml = (_defined_by_launcher())
? _launcher_xml->xml() : Xml_node("<empty/>");
Xml_node const start_xml = _start_xml->xml();
xml.node("start", [&] () { xml.node("start", [&] () {
xml.attribute("name", _name); xml.attribute("name", _name);
{
unsigned long caps = _pkg_cap_quota; unsigned long caps = _pkg_cap_quota;
if (_defined_by_launcher()) if (_defined_by_launcher())
caps = _launcher_xml->xml().attribute_value("caps", caps); caps = launcher_xml.attribute_value("caps", caps);
caps = _start_xml->xml().attribute_value("caps", caps); caps = start_xml.attribute_value("caps", caps);
xml.attribute("caps", caps); xml.attribute("caps", caps);
}
{
typedef String<64> Version; typedef String<64> Version;
Version const version = _start_xml->xml().attribute_value("version", Version()); Version const version = _start_xml->xml().attribute_value("version", Version());
if (version.valid()) if (version.valid())
xml.attribute("version", version); xml.attribute("version", version);
}
{
long priority = prio_levels.min_priority();
if (_defined_by_launcher())
priority = launcher_xml.attribute_value("priority", priority);
priority = start_xml.attribute_value("priority", priority);
if (priority)
xml.attribute("priority", priority);
}
bool shim_reroute = false; bool shim_reroute = false;
/* lookup if PD/CPU service is configured and use shim in such cases */ /* lookup if PD/CPU service is configured and use shim in such cases */
if (_start_xml->xml().has_sub_node("route")) { if (start_xml.has_sub_node("route")) {
Xml_node const route = _start_xml->xml().sub_node("route"); Xml_node const route = start_xml.sub_node("route");
route.for_each_sub_node("service", [&] (Xml_node const &service) { route.for_each_sub_node("service", [&] (Xml_node const &service) {
if (service.attribute_value("name", Name()) == "PD" || if (service.attribute_value("name", Name()) == "PD" ||
@ -366,8 +395,8 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
Number_of_bytes ram = _pkg_ram_quota; Number_of_bytes ram = _pkg_ram_quota;
if (_defined_by_launcher()) if (_defined_by_launcher())
ram = _launcher_xml->xml().attribute_value("ram", ram); ram = launcher_xml.attribute_value("ram", ram);
ram = _start_xml->xml().attribute_value("ram", ram); ram = start_xml.attribute_value("ram", ram);
xml.node("resource", [&] () { xml.node("resource", [&] () {
xml.attribute("name", "RAM"); xml.attribute("name", "RAM");
@ -376,8 +405,8 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
unsigned long cpu_quota = _pkg_cpu_quota; unsigned long cpu_quota = _pkg_cpu_quota;
if (_defined_by_launcher()) if (_defined_by_launcher())
cpu_quota = _launcher_xml->xml().attribute_value("cpu", cpu_quota); cpu_quota = launcher_xml.attribute_value("cpu", cpu_quota);
cpu_quota = _start_xml->xml().attribute_value("cpu", cpu_quota); cpu_quota = start_xml.attribute_value("cpu", cpu_quota);
xml.node("resource", [&] () { xml.node("resource", [&] () {
xml.attribute("name", "CPU"); xml.attribute("name", "CPU");
@ -386,20 +415,20 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
/* affinity-location handling */ /* affinity-location handling */
bool const affinity_from_launcher = _defined_by_launcher() bool const affinity_from_launcher = _defined_by_launcher()
&& _launcher_xml->xml().has_sub_node("affinity"); && launcher_xml.has_sub_node("affinity");
bool const affinity_from_start = _start_xml->xml().has_sub_node("affinity"); bool const affinity_from_start = start_xml.has_sub_node("affinity");
if (affinity_from_start || affinity_from_launcher) { if (affinity_from_start || affinity_from_launcher) {
Affinity::Location location { }; Affinity::Location location { };
if (affinity_from_launcher) if (affinity_from_launcher)
_launcher_xml->xml().with_sub_node("affinity", [&] (Xml_node node) { launcher_xml.with_sub_node("affinity", [&] (Xml_node node) {
location = Affinity::Location::from_xml(node); }); location = Affinity::Location::from_xml(node); });
if (affinity_from_start) if (affinity_from_start)
_start_xml->xml().with_sub_node("affinity", [&] (Xml_node node) { start_xml.with_sub_node("affinity", [&] (Xml_node node) {
location = Affinity::Location::from_xml(node); }); location = Affinity::Location::from_xml(node); });
xml.node("affinity", [&] () { xml.node("affinity", [&] () {
@ -416,20 +445,21 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, Xml_node common,
/* /*
* Insert inline '<heartbeat>' node if provided by the start node. * Insert inline '<heartbeat>' node if provided by the start node.
*/ */
if (_start_xml->xml().has_sub_node("heartbeat")) { if (start_xml.has_sub_node("heartbeat"))
_gen_copy_of_sub_node(xml, _start_xml->xml(), "heartbeat"); _gen_copy_of_sub_node(xml, start_xml, "heartbeat");
}
/* /*
* Insert inline '<config>' node if provided by the start node, * Insert inline '<config>' node if provided by the start node,
* the launcher definition (if a launcher is user), or the * the launcher definition (if a launcher is user), or the
* blueprint. The former is preferred over the latter. * blueprint. The former is preferred over the latter.
*/ */
if (_start_xml->xml().has_sub_node("config")) { if (start_xml.has_sub_node("config")) {
_gen_copy_of_sub_node(xml, _start_xml->xml(), "config"); _gen_copy_of_sub_node(xml, start_xml, "config");
} else { } else {
if (_defined_by_launcher() && _launcher_xml->xml().has_sub_node("config")) {
_gen_copy_of_sub_node(xml, _launcher_xml->xml(), "config"); if (_defined_by_launcher() && launcher_xml.has_sub_node("config")) {
_gen_copy_of_sub_node(xml, launcher_xml, "config");
} else { } else {
if (runtime.has_sub_node("config")) if (runtime.has_sub_node("config"))
_gen_copy_of_sub_node(xml, runtime, "config"); _gen_copy_of_sub_node(xml, runtime, "config");

View File

@ -114,11 +114,13 @@ class Depot_deploy::Children
} }
void gen_start_nodes(Xml_generator &xml, Xml_node common, void gen_start_nodes(Xml_generator &xml, Xml_node common,
Child::Prio_levels prio_levels,
Child::Depot_rom_server const &cached_depot_rom, Child::Depot_rom_server const &cached_depot_rom,
Child::Depot_rom_server const &uncached_depot_rom) const Child::Depot_rom_server const &uncached_depot_rom) const
{ {
_children.for_each([&] (Child const &child) { _children.for_each([&] (Child const &child) {
child.gen_start_node(xml, common, cached_depot_rom, uncached_depot_rom); }); child.gen_start_node(xml, common, prio_levels, cached_depot_rom,
uncached_depot_rom); });
} }
void gen_queries(Xml_generator &xml) const void gen_queries(Xml_generator &xml) const

View File

@ -66,6 +66,9 @@ struct Depot_deploy::Main
_children.apply_config(config); _children.apply_config(config);
_children.apply_blueprint(_blueprint.xml()); _children.apply_blueprint(_blueprint.xml());
Child::Prio_levels const prio_levels {
config.attribute_value("prio_levels", 0U) };
/* determine CPU architecture of deployment */ /* determine CPU architecture of deployment */
typedef String<16> Arch; typedef String<16> Arch;
Arch const arch = config.attribute_value("arch", Arch()); Arch const arch = config.attribute_value("arch", Arch());
@ -75,6 +78,9 @@ struct Depot_deploy::Main
/* generate init config containing all configured start nodes */ /* generate init config containing all configured start nodes */
_init_config_reporter.generate([&] (Xml_generator &xml) { _init_config_reporter.generate([&] (Xml_generator &xml) {
if (prio_levels.value)
xml.attribute("prio_levels", prio_levels.value);
Xml_node static_config = config.sub_node("static"); Xml_node static_config = config.sub_node("static");
static_config.with_raw_content([&] (char const *start, size_t length) { static_config.with_raw_content([&] (char const *start, size_t length) {
xml.append(start, length); }); xml.append(start, length); });
@ -123,7 +129,7 @@ struct Depot_deploy::Main
Child::Depot_rom_server const parent { }; Child::Depot_rom_server const parent { };
_children.gen_start_nodes(xml, config.sub_node("common_routes"), _children.gen_start_nodes(xml, config.sub_node("common_routes"),
parent, parent); prio_levels, parent, parent);
}); });
/* update query for blueprints of all unconfigured start nodes */ /* update query for blueprints of all unconfigured start nodes */

View File

@ -148,7 +148,8 @@ void Sculpt::Deploy::handle_deploy()
} }
void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml) const void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml,
Prio_levels prio_levels) const
{ {
/* depot-ROM instance for regular (immutable) depot content */ /* depot-ROM instance for regular (immutable) depot content */
xml.node("start", [&] () { xml.node("start", [&] () {
@ -175,5 +176,5 @@ void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml) const
/* generate start nodes for deployed packages */ /* generate start nodes for deployed packages */
if (managed_deploy.has_sub_node("common_routes")) if (managed_deploy.has_sub_node("common_routes"))
_children.gen_start_nodes(xml, managed_deploy.sub_node("common_routes"), _children.gen_start_nodes(xml, managed_deploy.sub_node("common_routes"),
"depot_rom", "dynamic_depot_rom"); prio_levels, "depot_rom", "dynamic_depot_rom");
} }

View File

@ -35,6 +35,8 @@ namespace Sculpt { struct Deploy; }
struct Sculpt::Deploy struct Sculpt::Deploy
{ {
typedef Depot_deploy::Child::Prio_levels Prio_levels;
Env &_env; Env &_env;
Allocator &_alloc; Allocator &_alloc;
@ -58,10 +60,12 @@ struct Sculpt::Deploy
Arch _arch { }; Arch _arch { };
Child_state cached_depot_rom_state { Child_state cached_depot_rom_state {
_child_states, "depot_rom", Ram_quota{24*1024*1024}, Cap_quota{200} }; _child_states, "depot_rom", Priority::STORAGE,
Ram_quota{24*1024*1024}, Cap_quota{200} };
Child_state uncached_depot_rom_state { Child_state uncached_depot_rom_state {
_child_states, "dynamic_depot_rom", Ram_quota{8*1024*1024}, Cap_quota{200} }; _child_states, "dynamic_depot_rom", Priority::STORAGE,
Ram_quota{8*1024*1024}, Cap_quota{200} };
/* /*
* Report written to '/config/managed/deploy' * Report written to '/config/managed/deploy'
@ -139,6 +143,7 @@ struct Sculpt::Deploy
copy_attribute("caps"); copy_attribute("caps");
copy_attribute("ram"); copy_attribute("ram");
copy_attribute("cpu"); copy_attribute("cpu");
copy_attribute("priority");
copy_attribute("pkg"); copy_attribute("pkg");
/* copy start-node content */ /* copy start-node content */
@ -227,7 +232,7 @@ struct Sculpt::Deploy
void gen_child_diagnostics(Xml_generator &xml) const; void gen_child_diagnostics(Xml_generator &xml) const;
void gen_runtime_start_nodes(Xml_generator &) const; void gen_runtime_start_nodes(Xml_generator &, Prio_levels) const;
Signal_handler<Deploy> _managed_deploy_handler { Signal_handler<Deploy> _managed_deploy_handler {
_env.ep(), *this, &Deploy::_handle_managed_deploy }; _env.ep(), *this, &Deploy::_handle_managed_deploy };

View File

@ -298,6 +298,8 @@ struct Sculpt::Main : Input_event_handler,
** Deploy ** ** Deploy **
************/ ************/
Deploy::Prio_levels const _prio_levels { 4 };
Attached_rom_dataspace _launcher_listing_rom { Attached_rom_dataspace _launcher_listing_rom {
_env, "report -> /runtime/launcher_query/listing" }; _env, "report -> /runtime/launcher_query/listing" };
@ -789,6 +791,7 @@ struct Sculpt::Main : Input_event_handler,
Start_name const start_name(name, ".query"); Start_name const start_name(name, ".query");
_file_browser_state.fs_query.construct(_child_states, start_name, _file_browser_state.fs_query.construct(_child_states, start_name,
Priority::LEITZENTRALE,
Ram_quota{8*1024*1024}, Cap_quota{200}); Ram_quota{8*1024*1024}, Cap_quota{200});
Label const rom_label("report -> /runtime/", start_name, "/listing"); Label const rom_label("report -> /runtime/", start_name, "/listing");
@ -851,6 +854,7 @@ struct Sculpt::Main : Input_event_handler,
} else { } else {
Start_name const start_name("editor"); Start_name const start_name("editor");
_file_browser_state.text_area.construct(_child_states, start_name, _file_browser_state.text_area.construct(_child_states, start_name,
Priority::LEITZENTRALE,
Ram_quota{16*1024*1024}, Cap_quota{250}); Ram_quota{16*1024*1024}, Cap_quota{250});
} }
} }
@ -1632,6 +1636,8 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
{ {
xml.attribute("verbose", "yes"); xml.attribute("verbose", "yes");
xml.attribute("prio_levels", _prio_levels.value);
xml.node("report", [&] () { xml.node("report", [&] () {
xml.attribute("init_ram", "yes"); xml.attribute("init_ram", "yes");
xml.attribute("init_caps", "yes"); xml.attribute("init_caps", "yes");
@ -1728,7 +1734,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const
xml.node("start", [&] () { xml.node("start", [&] () {
gen_launcher_query_start_content(xml); }); gen_launcher_query_start_content(xml); });
_deploy.gen_runtime_start_nodes(xml); _deploy.gen_runtime_start_nodes(xml, _prio_levels);
} }
} }

View File

@ -51,7 +51,7 @@ Menu_view::Menu_view(Env &env, Registry<Child_state> &registry,
Session_label const &hover_rom_name) Session_label const &hover_rom_name)
: :
_dialog(dialog), _dialog(dialog),
_child_state(registry, name, ram_quota, cap_quota), _child_state(registry, name, Priority::LEITZENTRALE, ram_quota, cap_quota),
_dialog_reporter(env, "dialog", dialog_report_name.string()), _dialog_reporter(env, "dialog", dialog_report_name.string()),
_hover_rom(env, hover_rom_name.string()), _hover_rom(env, hover_rom_name.string()),
_hover_handler(env.ep(), *this, &Menu_view::_handle_hover) _hover_handler(env.ep(), *this, &Menu_view::_handle_hover)

View File

@ -35,6 +35,8 @@ struct Sculpt::Child_state : Noncopyable
Start_name const _name; Start_name const _name;
Priority const _priority;
Ram_quota const _initial_ram_quota; Ram_quota const _initial_ram_quota;
Cap_quota const _initial_cap_quota; Cap_quota const _initial_cap_quota;
@ -52,10 +54,10 @@ struct Sculpt::Child_state : Noncopyable
* \param cap_quota initial capability quota * \param cap_quota initial capability quota
*/ */
Child_state(Registry<Child_state> &registry, Start_name const &name, Child_state(Registry<Child_state> &registry, Start_name const &name,
Ram_quota ram_quota, Cap_quota cap_quota) Priority priority, Ram_quota ram_quota, Cap_quota cap_quota)
: :
_element(registry, *this), _element(registry, *this),
_name(name), _name(name), _priority(priority),
_initial_ram_quota(ram_quota), _initial_cap_quota(cap_quota) _initial_ram_quota(ram_quota), _initial_cap_quota(cap_quota)
{ } { }
@ -79,6 +81,7 @@ struct Sculpt::Child_state : Noncopyable
gen_start_node_version(xml); gen_start_node_version(xml);
xml.attribute("caps", _cap_quota.value); xml.attribute("caps", _cap_quota.value);
xml.attribute("priority", (int)_priority);
gen_named_node(xml, "resource", "RAM", [&] () { gen_named_node(xml, "resource", "RAM", [&] () {
Number_of_bytes const bytes(_ram_quota.value); Number_of_bytes const bytes(_ram_quota.value);
xml.attribute("quantum", String<64>(bytes)); }); xml.attribute("quantum", String<64>(bytes)); });

View File

@ -26,9 +26,16 @@ namespace Sculpt { struct Ram_fs_state; }
struct Sculpt::Ram_fs_state : Child_state, File_system struct Sculpt::Ram_fs_state : Child_state, File_system
{ {
/*
* Use Priority::LEITZENTRALE for the RAM file system to make the
* inspect view available even in conditions when a malfunctioning
* high-priority driver is spinning.
*/
Ram_fs_state(Registry<Child_state> &registry, Start_name const &name) Ram_fs_state(Registry<Child_state> &registry, Start_name const &name)
: :
Child_state(registry, name, Ram_quota{1024*1024}, Cap_quota{300}), Child_state(registry, name, Priority::LEITZENTRALE,
Ram_quota{1024*1024}, Cap_quota{300}),
File_system(File_system::UNKNOWN) File_system(File_system::UNKNOWN)
{ } { }
}; };

View File

@ -215,7 +215,8 @@ void Sculpt::Storage_device::gen_part_block_start_content(Xml_generator &xml,
xml.attribute("version", _part_block_version); xml.attribute("version", _part_block_version);
gen_common_start_content(xml, Label(label, ".part_block"), gen_common_start_content(xml, Label(label, ".part_block"),
Cap_quota{100}, Ram_quota{8*1024*1024}); Cap_quota{100}, Ram_quota{8*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "part_block"); gen_named_node(xml, "binary", "part_block");

View File

@ -111,7 +111,8 @@ struct Sculpt::Usb_storage_device : List_model<Usb_storage_device>::Element,
void Sculpt::Usb_storage_device::gen_usb_block_drv_start_content(Xml_generator &xml) const void Sculpt::Usb_storage_device::gen_usb_block_drv_start_content(Xml_generator &xml) const
{ {
gen_common_start_content(xml, usb_block_drv_name(), gen_common_start_content(xml, usb_block_drv_name(),
Cap_quota{100}, Ram_quota{6*1024*1024}); Cap_quota{100}, Ram_quota{6*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "usb_block_drv"); gen_named_node(xml, "binary", "usb_block_drv");

View File

@ -16,7 +16,9 @@
void Sculpt::gen_chroot_start_content(Xml_generator &xml, Start_name const &name, void Sculpt::gen_chroot_start_content(Xml_generator &xml, Start_name const &name,
Path const &path, Writeable writable) Path const &path, Writeable writable)
{ {
gen_common_start_content(xml, name, Cap_quota{100}, Ram_quota{2*1024*1024}); gen_common_start_content(xml, name,
Cap_quota{100}, Ram_quota{2*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "chroot"); gen_named_node(xml, "binary", "chroot");

View File

@ -16,7 +16,8 @@
void Sculpt::gen_depot_query_start_content(Xml_generator &xml) void Sculpt::gen_depot_query_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "depot_query", gen_common_start_content(xml, "depot_query",
Cap_quota{200}, Ram_quota{2*1024*1024}); Cap_quota{200}, Ram_quota{2*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "depot_query"); gen_named_node(xml, "binary", "depot_query");

View File

@ -34,7 +34,8 @@ void Sculpt::gen_e2fs_start_content(Xml_generator &xml,
GEN_ARGS_FN const &gen_args_fn) GEN_ARGS_FN const &gen_args_fn)
{ {
gen_common_start_content(xml, String<64>(target.label(), ".", tool), gen_common_start_content(xml, String<64>(target.label(), ".", tool),
Cap_quota{500}, Ram_quota{100*1024*1024}); Cap_quota{500}, Ram_quota{100*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", tool); gen_named_node(xml, "binary", tool);

View File

@ -18,7 +18,8 @@ void Sculpt::gen_fs_start_content(Xml_generator &xml,
File_system::Type fs_type) File_system::Type fs_type)
{ {
gen_common_start_content(xml, target.fs(), gen_common_start_content(xml, target.fs(),
Cap_quota{400}, Ram_quota{64*1024*1024}); Cap_quota{400}, Ram_quota{64*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "vfs"); gen_named_node(xml, "binary", "vfs");

View File

@ -19,7 +19,8 @@ void Sculpt::gen_fs_tool_start_content(Xml_generator &xml, Fs_tool_version versi
{ {
xml.attribute("version", version.value); xml.attribute("version", version.value);
gen_common_start_content(xml, "fs_tool", Cap_quota{200}, Ram_quota{5*1024*1024}); gen_common_start_content(xml, "fs_tool", Cap_quota{200}, Ram_quota{5*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "fs_tool"); gen_named_node(xml, "binary", "fs_tool");

View File

@ -27,7 +27,8 @@ void Sculpt::_gen_gpt_write_start_content(Xml_generator &xml,
Start_name const &name, Start_name const &name,
GEN_ACTIONS_FN const &fn) GEN_ACTIONS_FN const &fn)
{ {
gen_common_start_content(xml, name, Cap_quota{100}, Ram_quota{2*1024*1024}); gen_common_start_content(xml, name, Cap_quota{100}, Ram_quota{2*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "gpt_write"); gen_named_node(xml, "binary", "gpt_write");

View File

@ -28,7 +28,9 @@ static void for_each_inspected_storage_target(Storage_devices const &devices, FN
static void gen_terminal_start(Xml_generator &xml) static void gen_terminal_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "terminal", Cap_quota{110}, Ram_quota{18*1024*1024}); gen_common_start_content(xml, "terminal",
Cap_quota{110}, Ram_quota{18*1024*1024},
Priority::LEITZENTRALE);
gen_provides<Terminal::Session>(xml); gen_provides<Terminal::Session>(xml);
@ -50,7 +52,9 @@ static void gen_vfs_start(Xml_generator &xml,
Storage_devices const &devices, Storage_devices const &devices,
Ram_fs_state const &ram_fs_state) Ram_fs_state const &ram_fs_state)
{ {
gen_common_start_content(xml, "vfs", Cap_quota{200}, Ram_quota{5*1024*1024}); gen_common_start_content(xml, "vfs",
Cap_quota{200}, Ram_quota{5*1024*1024},
Priority::LEITZENTRALE);
gen_provides<::File_system::Session>(xml); gen_provides<::File_system::Session>(xml);
@ -129,7 +133,9 @@ static void gen_vfs_start(Xml_generator &xml,
static void gen_fs_rom_start(Xml_generator &xml) static void gen_fs_rom_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "vfs_rom", Cap_quota{100}, Ram_quota{15*1024*1024}); gen_common_start_content(xml, "vfs_rom",
Cap_quota{100}, Ram_quota{15*1024*1024},
Priority::LEITZENTRALE);
gen_named_node(xml, "binary", "cached_fs_rom", [&] () { }); gen_named_node(xml, "binary", "cached_fs_rom", [&] () { });
@ -148,7 +154,9 @@ static void gen_fs_rom_start(Xml_generator &xml)
static void gen_bash_start(Xml_generator &xml) static void gen_bash_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "bash", Cap_quota{400}, Ram_quota{15*1024*1024}); gen_common_start_content(xml, "bash",
Cap_quota{400}, Ram_quota{15*1024*1024},
Priority::LEITZENTRALE);
gen_named_node(xml, "binary", "/bin/bash", [&] () { }); gen_named_node(xml, "binary", "/bin/bash", [&] () { });
@ -206,7 +214,8 @@ void Sculpt::gen_inspect_view(Xml_generator &xml,
xml.attribute("version", version.value); xml.attribute("version", version.value);
gen_common_start_content(xml, "inspect", gen_common_start_content(xml, "inspect",
Cap_quota{1000}, Ram_quota{76*1024*1024}); Cap_quota{1000}, Ram_quota{76*1024*1024},
Priority::LEITZENTRALE);
gen_named_node(xml, "binary", "init", [&] () { }); gen_named_node(xml, "binary", "init", [&] () { });

View File

@ -16,7 +16,8 @@
void Sculpt::gen_launcher_query_start_content(Xml_generator &xml) void Sculpt::gen_launcher_query_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "launcher_query", gen_common_start_content(xml, "launcher_query",
Cap_quota{200}, Ram_quota{2*1024*1024}); Cap_quota{200}, Ram_quota{2*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "fs_query"); gen_named_node(xml, "binary", "fs_query");

View File

@ -16,7 +16,10 @@
void Sculpt::gen_nic_drv_start_content(Xml_generator &xml) void Sculpt::gen_nic_drv_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "nic_drv", Cap_quota{300}, Ram_quota{16*1024*1024}); gen_common_start_content(xml, "nic_drv",
Cap_quota{300}, Ram_quota{16*1024*1024},
Priority::NETWORK);
gen_named_node(xml, "resource", "CPU", [&] () { xml.attribute("quantum", "50"); }); gen_named_node(xml, "resource", "CPU", [&] () { xml.attribute("quantum", "50"); });
xml.node("config", [&] () { xml.attribute("mode", "uplink_client"); }); xml.node("config", [&] () { xml.attribute("mode", "uplink_client"); });

View File

@ -21,7 +21,8 @@
void Sculpt::gen_nic_router_start_content(Xml_generator &xml) void Sculpt::gen_nic_router_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "nic_router", gen_common_start_content(xml, "nic_router",
Cap_quota{300}, Ram_quota{10*1024*1024}); Cap_quota{300}, Ram_quota{10*1024*1024},
Priority::NETWORK);
xml.node("provides", [&] () { xml.node("provides", [&] () {
xml.node("service", [&] () { xml.node("service", [&] () {

View File

@ -23,7 +23,9 @@ namespace Sculpt {
void Sculpt::gen_prepare_vfs_start(Xml_generator &xml) void Sculpt::gen_prepare_vfs_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "vfs", Cap_quota{200}, Ram_quota{5*1024*1024}); gen_common_start_content(xml, "vfs",
Cap_quota{200}, Ram_quota{5*1024*1024},
Priority::STORAGE);
char const * const script = char const * const script =
"export VERSION=`cat /VERSION`\n" "export VERSION=`cat /VERSION`\n"
@ -79,7 +81,9 @@ void Sculpt::gen_prepare_vfs_start(Xml_generator &xml)
void Sculpt::gen_prepare_fs_rom_start(Xml_generator &xml) void Sculpt::gen_prepare_fs_rom_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "vfs_rom", Cap_quota{100}, Ram_quota{15*1024*1024}); gen_common_start_content(xml, "vfs_rom",
Cap_quota{100}, Ram_quota{15*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "fs_rom", [&] () { }); gen_named_node(xml, "binary", "fs_rom", [&] () { });
@ -98,7 +102,9 @@ void Sculpt::gen_prepare_fs_rom_start(Xml_generator &xml)
void Sculpt::gen_prepare_bash_start(Xml_generator &xml) void Sculpt::gen_prepare_bash_start(Xml_generator &xml)
{ {
gen_common_start_content(xml, "bash", Cap_quota{400}, Ram_quota{15*1024*1024}); gen_common_start_content(xml, "bash",
Cap_quota{400}, Ram_quota{15*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "/bin/bash", [&] () { }); gen_named_node(xml, "binary", "/bin/bash", [&] () { });
@ -152,7 +158,9 @@ void Sculpt::gen_prepare_start_content(Xml_generator &xml, Prepare_version versi
{ {
xml.attribute("version", version.value); xml.attribute("version", version.value);
gen_common_start_content(xml, "prepare", Cap_quota{800}, Ram_quota{100*1024*1024}); gen_common_start_content(xml, "prepare",
Cap_quota{800}, Ram_quota{100*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "init"); gen_named_node(xml, "binary", "init");

View File

@ -15,7 +15,9 @@
void Sculpt::gen_update_start_content(Xml_generator &xml) void Sculpt::gen_update_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "update", Cap_quota{2000}, Ram_quota{64*1024*1024}); gen_common_start_content(xml, "update",
Cap_quota{2000}, Ram_quota{64*1024*1024},
Priority::STORAGE);
gen_named_node(xml, "binary", "init"); gen_named_node(xml, "binary", "init");

View File

@ -15,7 +15,9 @@
void Sculpt::gen_wifi_drv_start_content(Xml_generator &xml) void Sculpt::gen_wifi_drv_start_content(Xml_generator &xml)
{ {
gen_common_start_content(xml, "wifi_drv", Cap_quota{200}, Ram_quota{32*1024*1024}); gen_common_start_content(xml, "wifi_drv",
Cap_quota{200}, Ram_quota{32*1024*1024},
Priority::NETWORK);
xml.node("config", [&] () { xml.node("config", [&] () {

View File

@ -47,6 +47,19 @@ namespace Sculpt {
typedef Gui::Area Area; typedef Gui::Area Area;
enum Writeable { WRITEABLE, READ_ONLY }; enum Writeable { WRITEABLE, READ_ONLY };
/*
* CPU priorities used within the runtime subsystem
*/
enum class Priority {
BACKGROUND = -3,
DEFAULT = -2,
NETWORK = DEFAULT,
STORAGE = DEFAULT,
MULTIMEDIA = -1,
DRIVER = 0,
LEITZENTRALE = 0 /* only for latency-critical drivers */
};
} }
#endif /* _TYPES_H_ */ #endif /* _TYPES_H_ */

View File

@ -97,10 +97,12 @@ namespace Sculpt {
static inline void gen_common_start_content(Xml_generator &xml, static inline void gen_common_start_content(Xml_generator &xml,
Rom_name const &name, Rom_name const &name,
Cap_quota const caps, Cap_quota const caps,
Ram_quota const ram) Ram_quota const ram,
Priority const priority)
{ {
xml.attribute("name", name); xml.attribute("name", name);
xml.attribute("caps", caps.value); xml.attribute("caps", caps.value);
xml.attribute("priority", (int)priority);
gen_named_node(xml, "resource", "RAM", [&] () { gen_named_node(xml, "resource", "RAM", [&] () {
xml.attribute("quantum", String<64>(Number_of_bytes(ram.value))); }); xml.attribute("quantum", String<64>(Number_of_bytes(ram.value))); });
} }