diff --git a/repos/os/run/resource_request.run b/repos/os/run/resource_request.run index 7fa6861405..342381130a 100644 --- a/repos/os/run/resource_request.run +++ b/repos/os/run/resource_request.run @@ -1,4 +1,4 @@ -build "core init test/resource_request drivers/timer" +build "core init server/report_rom test/resource_request drivers/timer" create_boot_directory @@ -8,7 +8,6 @@ install_config { - @@ -22,14 +21,34 @@ install_config { - + - + + + + + + + + + + + + + + + + + + + + + } -build_boot_image "core ld.lib.so init timer test-resource_request" +build_boot_image "core ld.lib.so init timer report_rom test-resource_request" append qemu_args "-nographic -m 128" diff --git a/repos/os/src/test/resource_request/main.cc b/repos/os/src/test/resource_request/main.cc index c479b16f1f..37110ff1bf 100644 --- a/repos/os/src/test/resource_request/main.cc +++ b/repos/os/src/test/resource_request/main.cc @@ -16,7 +16,14 @@ #include #include +#include #include +#include + +namespace Test { + using namespace Genode; + struct Monitor; +} static void print_quota_stats(Genode::Ram_session &ram) @@ -31,10 +38,99 @@ static void print_quota_stats(Genode::Ram_session &ram) throw Error(); } +struct Test::Monitor +{ + Env &_env; + + Attached_rom_dataspace _init_state { _env, "state" }; + + Reporter _init_config { _env, "init.config" }; + + size_t _ram_quota = 2*1024*1024; + + void _gen_service_xml(Xml_generator &xml, char const *name) + { + xml.node("service", [&] () { xml.attribute("name", name); }); + }; + + void _generate_init_config() + { + Reporter::Xml_generator xml(_init_config, [&] () { + + xml.node("report", [&] () { xml.attribute("child_ram", true); }); + + xml.node("parent-provides", [&] () { + _gen_service_xml(xml, "ROM"); + _gen_service_xml(xml, "CPU"); + _gen_service_xml(xml, "PD"); + _gen_service_xml(xml, "RAM"); + _gen_service_xml(xml, "LOG"); + _gen_service_xml(xml, "Timer"); + }); + + xml.node("start", [&] () { + xml.attribute("name", "test-resource_request"); + xml.node("resource", [&] () { + xml.attribute("name", "RAM"); + xml.attribute("quantum", _ram_quota); + }); + xml.node("route", [&] () { + xml.node("any-service", [&] () { + xml.node("parent", [&] () { }); }); }); + }); + }); + } + + size_t _resource_request_from_init_state() + { + try { + return _init_state.xml().sub_node("child") + .sub_node("ram") + .attribute_value("requested", Number_of_bytes(0)); + } + catch (...) { return 0; } + } + + Signal_handler _init_state_handler { + _env.ep(), *this, &Monitor::_handle_init_state }; + + void _handle_init_state() + { + _init_state.update(); + + size_t const requested = _resource_request_from_init_state(); + if (requested > 0) { + log("responding to resource request of ", Number_of_bytes(requested)); + + _ram_quota += requested; + _generate_init_config(); + } + } + + Monitor(Env &env) : _env(env) + { + _init_config.enabled(true); + _init_state.sigh(_init_state_handler); + _generate_init_config(); + } +}; + + void Component::construct(Genode::Env &env) { using namespace Genode; + /* + * Distinguish the roles of the program. If configured as playing the + * monitor role, it manages the configuration of a sub init and monitors + * the init state for resource requests. + */ + Attached_rom_dataspace config { env, "config" }; + if (config.xml().attribute_value("role", String<32>()) == "monitor") { + static Test::Monitor monitor(env); + return; + } + class Error : Exception { }; log("--- test-resource_request started ---");