diff --git a/repos/gems/src/app/launcher/main.cc b/repos/gems/src/app/launcher/main.cc index c8dd9c58dd..1b10dfa3eb 100644 --- a/repos/gems/src/app/launcher/main.cc +++ b/repos/gems/src/app/launcher/main.cc @@ -78,7 +78,7 @@ struct Launcher::Main return 0; } - Subsystem_manager _subsystem_manager { _env.ep(), _env.pd(), + Subsystem_manager _subsystem_manager { _env, _ram_preservation(_config.xml()), _exited_child_handler }; diff --git a/repos/gems/src/app/launcher/subsystem_manager.h b/repos/gems/src/app/launcher/subsystem_manager.h index 5bf7af7b54..59d1c55cc1 100644 --- a/repos/gems/src/app/launcher/subsystem_manager.h +++ b/repos/gems/src/app/launcher/subsystem_manager.h @@ -25,6 +25,7 @@ namespace Launcher { class Subsystem_manager; using Decorator::string_attribute; + using Cli_monitor::Ram; using namespace Genode; } @@ -40,12 +41,11 @@ class Launcher::Subsystem_manager private: - Entrypoint &_ep; - Pd_session &_pd; - + Env & _env; + Heap _heap { _env.ram(), _env.rm() }; size_t const _ram_preservation; - struct Child : Child_base, List::Element + struct Child : Cli_monitor::Child_base, List::Element { template Child(ARGS &&... args) : Child_base(args...) { } @@ -60,7 +60,7 @@ class Launcher::Subsystem_manager } Signal_handler _yield_broadcast_handler = - { _ep, *this, &Subsystem_manager::_handle_yield_broadcast }; + { _env.ep(), *this, &Subsystem_manager::_handle_yield_broadcast }; void _handle_yield_broadcast() { @@ -90,7 +90,7 @@ class Launcher::Subsystem_manager } Signal_handler _resource_avail_handler = - { _ep, *this, &Subsystem_manager::_handle_resource_avail }; + { _env.ep(), *this, &Subsystem_manager::_handle_resource_avail }; void _handle_resource_avail() { @@ -98,7 +98,7 @@ class Launcher::Subsystem_manager } Signal_handler _yield_response_handler = - { _ep, *this, &Subsystem_manager::_handle_yield_response }; + { _env.ep(), *this, &Subsystem_manager::_handle_yield_response }; void _handle_yield_response() { @@ -107,7 +107,9 @@ class Launcher::Subsystem_manager Genode::Signal_context_capability _exited_child_sig_cap; - Ram _ram { _ram_preservation, + Ram _ram { _env.ram(), + _env.ram_session_cap(), + _ram_preservation, _yield_broadcast_handler, _resource_avail_handler }; @@ -147,11 +149,11 @@ class Launcher::Subsystem_manager public: - Subsystem_manager(Genode::Entrypoint &ep, Pd_session &pd, + Subsystem_manager(Genode::Env & env, size_t ram_preservation, Genode::Signal_context_capability exited_child_sig_cap) : - _ep(ep), _pd(pd), _ram_preservation(ram_preservation), + _env(env), _ram_preservation(ram_preservation), _exited_child_sig_cap(exited_child_sig_cap) { } @@ -172,12 +174,12 @@ class Launcher::Subsystem_manager Genode::log("starting child '", label.string(), "'"); try { - Child *child = new (env()->heap()) + Child *child = new (_heap) Child(_ram, label, binary_name.string(), - *Genode::env()->pd_session(), - *Genode::env()->ram_session(), - Genode::env()->ram_session_cap(), - *Genode::env()->rm_session(), + _env.pd(), + _env.ram(), + _env.ram_session_cap(), + _env.rm(), ram_config.quantum, ram_config.limit, _yield_broadcast_handler, _exited_child_sig_cap); @@ -203,7 +205,7 @@ class Launcher::Subsystem_manager for (Child *c = _children.first(); c; c = c->next()) { if (c->label() == Label(label)) { _children.remove(c); - destroy(env()->heap(), c); + destroy(_heap, c); return; } } diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h index 227a606218..8eee714884 100644 --- a/repos/os/include/cli_monitor/child.h +++ b/repos/os/include/cli_monitor/child.h @@ -27,8 +27,10 @@ /* CLI-monitor includes */ #include +namespace Cli_monitor { class Child_base; } -class Child_base : public Genode::Child_policy + +class Cli_monitor::Child_base : public Genode::Child_policy { public: diff --git a/repos/os/include/cli_monitor/ram.h b/repos/os/include/cli_monitor/ram.h index 1da5ebfe5e..304fff2f9c 100644 --- a/repos/os/include/cli_monitor/ram.h +++ b/repos/os/include/cli_monitor/ram.h @@ -17,15 +17,19 @@ /* Genode includes */ #include -class Ram +namespace Cli_monitor { class Ram; } + + +class Cli_monitor::Ram { private: typedef Genode::size_t size_t; + Genode::Ram_session &_ram; + Genode::Ram_session_capability _ram_cap; + Genode::Lock mutable _lock; - Genode::Ram_session &_ram = *Genode::env()->ram_session(); - Genode::Ram_session_capability _ram_cap = Genode::env()->ram_session_cap(); Genode::Signal_context_capability _yield_sigh; Genode::Signal_context_capability _resource_avail_sigh; @@ -50,10 +54,13 @@ class Ram : quota(quota), used(used), avail(avail), preserve(preserve) { } }; - Ram(size_t preserve, + Ram(Genode::Ram_session &ram, + Genode::Ram_session_capability ram_cap, + size_t preserve, Genode::Signal_context_capability yield_sigh, Genode::Signal_context_capability resource_avail_sigh) : + _ram(ram), _ram_cap(ram_cap), _yield_sigh(yield_sigh), _resource_avail_sigh(resource_avail_sigh), _preserve(preserve) @@ -128,10 +135,7 @@ class Ram throw Transfer_quota_failed(); } - /** - * Return singleton object - */ - static Ram &ram(); + size_t avail() const { return _ram.avail(); } }; #endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */ diff --git a/repos/os/lib/mk/cli_monitor.mk b/repos/os/lib/mk/cli_monitor.mk deleted file mode 100644 index f726c4628e..0000000000 --- a/repos/os/lib/mk/cli_monitor.mk +++ /dev/null @@ -1,4 +0,0 @@ -SRC_CC = no_extension.cc -INC_DIR += $(REP_DIR)/src/app/cli_monitor - -vpath no_extension.cc $(REP_DIR)/src/app/cli_monitor diff --git a/repos/os/lib/mk/foc_cli_monitor.mk b/repos/os/lib/mk/foc_cli_monitor.mk deleted file mode 100644 index 01e58a8d3b..0000000000 --- a/repos/os/lib/mk/foc_cli_monitor.mk +++ /dev/null @@ -1,7 +0,0 @@ -SRC_CC = extension.cc -REQUIRES = foc -INC_DIR += $(REP_DIR)/src/app/cli_monitor \ - $(REP_DIR)/src/app/cli_monitor/spec/foc -LIBS += syscall-foc - -vpath extension.cc $(REP_DIR)/src/app/cli_monitor/spec/foc diff --git a/repos/os/lib/mk/spec/arndale/foc_cli_monitor.mk b/repos/os/lib/mk/spec/arndale/foc_cli_monitor.mk deleted file mode 100644 index 9f7fed970b..0000000000 --- a/repos/os/lib/mk/spec/arndale/foc_cli_monitor.mk +++ /dev/null @@ -1,7 +0,0 @@ -SRC_CC = extension.cc -REQUIRES = foc_arndale -INC_DIR += $(REP_DIR)/src/app/cli_monitor \ - $(REP_DIR)/src/app/cli_monitor/spec/foc -LIBS += syscall-foc - -vpath extension.cc $(REP_DIR)/src/app/cli_monitor/spec/foc/arndale diff --git a/repos/os/lib/mk/spec/foc/cli_monitor.mk b/repos/os/lib/mk/spec/foc/cli_monitor.mk deleted file mode 100644 index f50ba5eada..0000000000 --- a/repos/os/lib/mk/spec/foc/cli_monitor.mk +++ /dev/null @@ -1 +0,0 @@ -LIBS += foc_cli_monitor \ No newline at end of file diff --git a/repos/os/src/app/cli_monitor/child.h b/repos/os/src/app/cli_monitor/child.h index a4f1d6ea3e..770774e4d3 100644 --- a/repos/os/src/app/cli_monitor/child.h +++ b/repos/os/src/app/cli_monitor/child.h @@ -20,7 +20,10 @@ /* local includes */ #include -struct Child : Child_base, List::Element +namespace Cli_monitor { struct Child; } + + +struct Cli_monitor::Child : Child_base, List::Element { Argument argument; diff --git a/repos/os/src/app/cli_monitor/child_registry.h b/repos/os/src/app/cli_monitor/child_registry.h index ffc7623f91..8fd236cd32 100644 --- a/repos/os/src/app/cli_monitor/child_registry.h +++ b/repos/os/src/app/cli_monitor/child_registry.h @@ -20,7 +20,10 @@ /* local includes */ #include -class Child_registry : public List +namespace Cli_monitor { class Child_registry; } + + +class Cli_monitor::Child_registry : public List { private: diff --git a/repos/os/src/app/cli_monitor/command_line.h b/repos/os/src/app/cli_monitor/command_line.h index e185202fe6..86155e629f 100644 --- a/repos/os/src/app/cli_monitor/command_line.h +++ b/repos/os/src/app/cli_monitor/command_line.h @@ -16,7 +16,10 @@ #include -class Command_line +namespace Cli_monitor { class Command_line; } + + +class Cli_monitor::Command_line { private: diff --git a/repos/os/src/app/cli_monitor/extension.h b/repos/os/src/app/cli_monitor/extension.h deleted file mode 100644 index 7633bb453e..0000000000 --- a/repos/os/src/app/cli_monitor/extension.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * \brief Interface for platform-specific CLI-monitor commands - * \author Norman Feske - * \date 2013-03-21 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _EXTENSION_H_ -#define _EXTENSION_H_ - -/* local includes */ -#include - -/** - * Initialize and register platform-specific commands - */ -void init_extension(Command_registry &); - -#endif /* _EXTENSION_H_ */ diff --git a/repos/os/src/app/cli_monitor/format_util.h b/repos/os/src/app/cli_monitor/format_util.h index 3fb1e32f6c..2f82e8c52d 100644 --- a/repos/os/src/app/cli_monitor/format_util.h +++ b/repos/os/src/app/cli_monitor/format_util.h @@ -17,96 +17,98 @@ /* local includes */ #include +namespace Cli_monitor { -/** - * Print rational number with two fractional decimals - */ -static inline size_t format_number(char *dst, size_t len, size_t const value, - size_t const quotient, char const *unit) -{ - size_t const integer = value / quotient; - size_t const n = snprintf(dst, len, "%ld.", integer); - size_t const remainder = ((value - (integer * quotient))*100) / quotient; - - if (len == n) return n; - - return n + snprintf(dst + n, len - n, "%s%ld%s", - remainder < 10 ? "0" : "", remainder, unit); -} - - -/** - * Print number of bytes using the best suitable unit - */ -static inline size_t format_bytes(char *dst, size_t len, size_t bytes) -{ - enum { KB = 1024, MB = 1024*KB }; - - if (bytes > MB) - return format_number(dst, len, bytes, MB, " MiB"); - - if (bytes > KB) - return format_number(dst, len, bytes, KB, " KiB"); - - return snprintf(dst, len, "%ld bytes", bytes); -} - - -/** - * Print number in MiB, without unit - */ -static inline size_t format_mib(char *dst, size_t len, size_t bytes) -{ - enum { KB = 1024, MB = 1024*KB }; - - return format_number(dst, len, bytes, MB , ""); -} - - -static inline size_t format_bytes(size_t bytes) -{ - char buf[128]; - return format_bytes(buf, sizeof(buf), bytes); -} - - -static inline size_t format_mib(size_t bytes) -{ - char buf[128]; - return format_mib(buf, sizeof(buf), bytes); -} - - -static inline void tprint_bytes(Terminal::Session &terminal, size_t bytes) -{ - char buf[128]; - format_bytes(buf, sizeof(buf), bytes); - Terminal::tprintf(terminal, "%s", buf); -} - - -static inline void tprint_mib(Terminal::Session &terminal, size_t bytes) -{ - char buf[128]; - format_mib(buf, sizeof(buf), bytes); - Terminal::tprintf(terminal, "%s", buf); -} - - -static inline void tprint_status_bytes(Terminal::Session &terminal, - char const *label, size_t bytes) -{ - Terminal::tprintf(terminal, label); - tprint_bytes(terminal, bytes); - Terminal::tprintf(terminal, "\n"); -} - - -static void tprint_padding(Terminal::Session &terminal, size_t pad, char c = ' ') -{ - char const buf[2] = { c, 0 }; - for (unsigned i = 0; i < pad; i++) - Terminal::tprintf(terminal, buf); + /** + * Print rational number with two fractional decimals + */ + static inline size_t format_number(char *dst, size_t len, size_t const value, + size_t const quotient, char const *unit) + { + size_t const integer = value / quotient; + size_t const n = snprintf(dst, len, "%ld.", integer); + size_t const remainder = ((value - (integer * quotient))*100) / quotient; + + if (len == n) return n; + + return n + snprintf(dst + n, len - n, "%s%ld%s", + remainder < 10 ? "0" : "", remainder, unit); + } + + + /** + * Print number of bytes using the best suitable unit + */ + static inline size_t format_bytes(char *dst, size_t len, size_t bytes) + { + enum { KB = 1024, MB = 1024*KB }; + + if (bytes > MB) + return format_number(dst, len, bytes, MB, " MiB"); + + if (bytes > KB) + return format_number(dst, len, bytes, KB, " KiB"); + + return snprintf(dst, len, "%ld bytes", bytes); + } + + + /** + * Print number in MiB, without unit + */ + static inline size_t format_mib(char *dst, size_t len, size_t bytes) + { + enum { KB = 1024, MB = 1024*KB }; + + return format_number(dst, len, bytes, MB , ""); + } + + + static inline size_t format_bytes(size_t bytes) + { + char buf[128]; + return format_bytes(buf, sizeof(buf), bytes); + } + + + static inline size_t format_mib(size_t bytes) + { + char buf[128]; + return format_mib(buf, sizeof(buf), bytes); + } + + + static inline void tprint_bytes(Terminal::Session &terminal, size_t bytes) + { + char buf[128]; + format_bytes(buf, sizeof(buf), bytes); + Terminal::tprintf(terminal, "%s", buf); + } + + + static inline void tprint_mib(Terminal::Session &terminal, size_t bytes) + { + char buf[128]; + format_mib(buf, sizeof(buf), bytes); + Terminal::tprintf(terminal, "%s", buf); + } + + + static inline void tprint_status_bytes(Terminal::Session &terminal, + char const *label, size_t bytes) + { + Terminal::tprintf(terminal, label); + tprint_bytes(terminal, bytes); + Terminal::tprintf(terminal, "\n"); + } + + + static void tprint_padding(Terminal::Session &terminal, size_t pad, char c = ' ') + { + char const buf[2] = { c, 0 }; + for (unsigned i = 0; i < pad; i++) + Terminal::tprintf(terminal, buf); + } } #endif /* _FORMAT_UTIL_H_ */ diff --git a/repos/os/src/app/cli_monitor/help_command.h b/repos/os/src/app/cli_monitor/help_command.h index 6289429496..30010a2e43 100644 --- a/repos/os/src/app/cli_monitor/help_command.h +++ b/repos/os/src/app/cli_monitor/help_command.h @@ -14,7 +14,10 @@ #ifndef _HELP_COMMAND_H_ #define _HELP_COMMAND_H_ -struct Help_command : Command +namespace Cli_monitor { struct Help_command; } + + +struct Cli_monitor::Help_command : Command { Help_command() : Command("help", "brief help information") { } diff --git a/repos/os/src/app/cli_monitor/kill_command.h b/repos/os/src/app/cli_monitor/kill_command.h index d54cc0df57..e09cd4c6a2 100644 --- a/repos/os/src/app/cli_monitor/kill_command.h +++ b/repos/os/src/app/cli_monitor/kill_command.h @@ -17,23 +17,29 @@ /* local includes */ #include -struct Kill_command : Command +namespace Cli_monitor { struct Kill_command; } + + +struct Cli_monitor::Kill_command : Command { Child_registry &_children; + Genode::Allocator &_alloc; + + Parameter _kill_all_param { "--all", Parameter::VOID, "kill all subsystems" }; + void _destroy_child(Child *child, Terminal::Session &terminal) { tprintf(terminal, "destroying subsystem '%s'\n", child->name().string()); _children.remove(child); - Genode::destroy(Genode::env()->heap(), child); + Genode::destroy(_alloc, child); } - Kill_command(Child_registry &children) + Kill_command(Child_registry &children, Genode::Allocator &alloc) : - Command("kill", "destroy subsystem"), - _children(children) + Command("kill", "destroy subsystem"), _children(children), _alloc(alloc) { - add_parameter(new Parameter("--all", Parameter::VOID, "kill all subsystems")); + add_parameter(_kill_all_param); } void _for_each_argument(Argument_fn const &fn) const override diff --git a/repos/os/src/app/cli_monitor/line_editor.h b/repos/os/src/app/cli_monitor/line_editor.h index 8fd917d189..fd34377c49 100644 --- a/repos/os/src/app/cli_monitor/line_editor.h +++ b/repos/os/src/app/cli_monitor/line_editor.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include #include #include #include @@ -23,17 +24,33 @@ #include #include -using Genode::List; -using Genode::max; -using Genode::strlen; -using Genode::strncpy; -using Genode::snprintf; -using Genode::strcmp; -using Genode::size_t; -using Genode::off_t; +namespace Cli_monitor { + + using Genode::Registry; + using Genode::List; + using Genode::max; + using Genode::strlen; + using Genode::strncpy; + using Genode::snprintf; + using Genode::strcmp; + using Genode::size_t; + using Genode::off_t; + + struct Completable; + struct Argument; + struct Parameter; + struct Command_line; + struct Command; + struct Command_registry; + struct Scanner_policy; + struct Argument_tracker; + struct Line_editor; + + typedef Genode::Token Token; +} -struct Completable +struct Cli_monitor::Completable { typedef Genode::String<64> Name; typedef Genode::String<160> Short_help; @@ -52,7 +69,7 @@ struct Completable /** * Representation of normal command-line argument */ -struct Argument : Completable +struct Cli_monitor::Argument : Completable { Argument(char const *name, char const *short_help) : Completable(name, short_help) { } @@ -64,7 +81,7 @@ struct Argument : Completable /** * Representation of a parameter of the form '--tag value' */ -struct Parameter : List::Element, Completable +struct Cli_monitor::Parameter : List::Element, Completable { enum Type { IDENT, NUMBER, VOID }; @@ -89,13 +106,10 @@ struct Parameter : List::Element, Completable }; -struct Command_line; - - /** * Representation of a command that can have arguments and parameters */ -struct Command : List::Element, Completable +struct Cli_monitor::Command : List::Element, Completable { List _parameters; @@ -110,7 +124,7 @@ struct Command : List::Element, Completable Command(char const *name, char const *short_help) : Completable(name, short_help) { } - void add_parameter(Parameter *par) { _parameters.insert(par); } + void add_parameter(Parameter &par) { _parameters.insert(&par); } char const *name_suffix() const { return ""; } @@ -141,13 +155,13 @@ struct Command : List::Element, Completable }; -struct Command_registry : List { }; +struct Cli_monitor::Command_registry : List { }; /** * Scanner policy that accepts '-', '.' and '_' as valid identifier characters */ -struct Scanner_policy +struct Cli_monitor::Scanner_policy { static bool identifier_char(char c, unsigned i) { @@ -157,13 +171,10 @@ struct Scanner_policy }; -typedef Genode::Token Token; - - /** * State machine used for sequentially parsing command-line arguments */ -struct Argument_tracker +struct Cli_monitor::Argument_tracker { private: @@ -288,7 +299,7 @@ struct Argument_tracker /** * Editing and completion logic */ -class Line_editor +class Cli_monitor::Line_editor { private: @@ -482,7 +493,7 @@ class Line_editor && strlen(curr->name()) == tag.len()) return curr; } - return 0; + return nullptr; } Command *_lookup_matching_command() @@ -492,7 +503,7 @@ class Line_editor if (strcmp(cmd.start(), curr->name().string(), cmd.len()) == 0 && _cursor_pos > cmd.len()) return curr; - return 0; + return nullptr; } template diff --git a/repos/os/src/app/cli_monitor/main.cc b/repos/os/src/app/cli_monitor/main.cc index 5e30186b1d..684c5c37cc 100644 --- a/repos/os/src/app/cli_monitor/main.cc +++ b/repos/os/src/app/cli_monitor/main.cc @@ -12,8 +12,8 @@ */ /* Genode includes */ -#include -#include +#include +#include #include #include #include @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -33,12 +32,10 @@ #include #include -using Genode::Xml_node; +namespace Cli_monitor { - -inline void *operator new (__SIZE_TYPE__ size) -{ - return Genode::env()->heap()->alloc(size); + struct Main; + using namespace Genode; } @@ -46,186 +43,187 @@ inline void *operator new (__SIZE_TYPE__ size) ** Main program ** ******************/ -static inline Command *lookup_command(char const *buf, Command_registry ®istry) +struct Cli_monitor::Main { - Token token(buf); - for (Command *curr = registry.first(); curr; curr = curr->next()) - if (strcmp(token.start(), curr->name().string(), token.len()) == 0 - && strlen(curr->name().string()) == token.len()) - return curr; - return 0; -} + Genode::Env &_env; + Terminal::Connection _terminal { _env }; -static size_t ram_preservation_from_config() -{ - Genode::Number_of_bytes ram_preservation = 0; - try { - Genode::Xml_node node = - Genode::config()->xml_node().sub_node("preservation"); + Command_registry _commands; - if (node.attribute("name").has_value("RAM")) - node.attribute("quantum").value(&ram_preservation); - } catch (...) { } + Child_registry _children; - return ram_preservation; -} - - -static Genode::Xml_node vfs_config() -{ - try { return Genode::config()->xml_node().sub_node("vfs"); } - catch (Genode::Xml_node::Nonexistent_sub_node) { - Genode::error("missing '' configuration"); - throw; + Command *_lookup_command(char const *buf) + { + Token token(buf); + for (Command *curr = _commands.first(); curr; curr = curr->next()) + if (strcmp(token.start(), curr->name().string(), token.len()) == 0 + && strlen(curr->name().string()) == token.len()) + return curr; + return 0; } -} - - -void Component::construct(Genode::Env &env) -{ - using Genode::Signal_context; - using Genode::Signal_context_capability; - using Genode::Signal_receiver; - - static Genode::Cap_connection cap; - static Terminal::Connection terminal(env); - static Command_registry commands; - static Child_registry children; - - /* initialize platform-specific commands */ - init_extension(commands); - - static Signal_receiver sig_rec; - static Signal_context read_avail_sig_ctx; - terminal.read_avail_sigh(sig_rec.manage(&read_avail_sig_ctx)); - - static Signal_context yield_response_sig_ctx; - static Signal_context_capability yield_response_sig_cap = - sig_rec.manage(&yield_response_sig_ctx); - - static Signal_context yield_broadcast_sig_ctx; - static Signal_context resource_avail_sig_ctx; - - static Signal_context exited_child_sig_ctx; - static Signal_context_capability exited_child_sig_cap = - sig_rec.manage(&exited_child_sig_ctx); - - static Ram ram(ram_preservation_from_config(), - sig_rec.manage(&yield_broadcast_sig_ctx), - sig_rec.manage(&resource_avail_sig_ctx)); - - /* initialize virtual file system */ - static Vfs::Dir_file_system root_dir(env, *Genode::env()->heap(), vfs_config(), - Vfs::global_file_system_factory()); - - static Subsystem_config_registry subsystem_config_registry(root_dir); - - /* initialize generic commands */ - commands.insert(new Help_command); - Kill_command kill_command(children); - commands.insert(&kill_command); - commands.insert(new Start_command(ram, env.pd(), - env.ram(), env.ram_session_cap(), - env.rm(), children, - subsystem_config_registry, - yield_response_sig_cap, - exited_child_sig_cap)); - commands.insert(new Status_command(ram, children)); - commands.insert(new Yield_command(children)); - commands.insert(new Ram_command(children)); enum { COMMAND_MAX_LEN = 1000 }; - static char buf[COMMAND_MAX_LEN]; - static Line_editor line_editor("genode> ", buf, sizeof(buf), terminal, commands); + char _command_buf[COMMAND_MAX_LEN]; + Line_editor _line_editor { + "genode> ", _command_buf, sizeof(_command_buf), _terminal, _commands }; - for (;;) { + void _handle_terminal_read_avail(); - /* block for event, e.g., the arrival of new user input */ - Genode::Signal signal = sig_rec.wait_for_signal(); + Signal_handler
_terminal_read_avail_handler { + _env.ep(), *this, &Main::_handle_terminal_read_avail }; - if (signal.context() == &read_avail_sig_ctx) { - - /* supply pending terminal input to line editor */ - while (terminal.avail() && !line_editor.completed()) { - char c; - terminal.read(&c, 1); - line_editor.submit_input(c); - } - } - - if (signal.context() == &yield_response_sig_ctx - || signal.context() == &resource_avail_sig_ctx) { - - for (Child *child = children.first(); child; child = child->next()) - child->try_response_to_resource_request(); - } - - if (signal.context() == &yield_broadcast_sig_ctx) { - - /* - * Compute argument of yield request to be broadcasted to all - * processes. - */ - size_t amount = 0; - - /* amount needed to reach preservation limit */ - Ram::Status ram_status = ram.status(); - if (ram_status.avail < ram_status.preserve) - amount += ram_status.preserve - ram_status.avail; - - /* sum of pending resource requests */ - for (Child *child = children.first(); child; child = child->next()) - amount += child->requested_ram_quota(); - - for (Child *child = children.first(); child; child = child->next()) - child->yield(amount, true); - } - - if (signal.context() == &exited_child_sig_ctx) { - Child *next = nullptr; - for (Child *child = children.first(); child; child = next) { - next = child->next(); - if (child->exited()) { - children.remove(child); - Genode::destroy(Genode::env()->heap(), child); - } - } - continue; - } - - if (!line_editor.completed()) - continue; - - Command *command = lookup_command(buf, commands); - if (!command) { - Token cmd_name(buf); - tprintf(terminal, "Error: unknown command \""); - terminal.write(cmd_name.start(), cmd_name.len()); - tprintf(terminal, "\"\n"); - line_editor.reset(); - continue; - } - - /* validate parameters against command meta data */ - Command_line cmd_line(buf, *command); - Token unexpected = cmd_line.unexpected_parameter(); - if (unexpected) { - tprintf(terminal, "Error: unexpected parameter \""); - terminal.write(unexpected.start(), unexpected.len()); - tprintf(terminal, "\"\n"); - line_editor.reset(); - continue; - } - command->execute(cmd_line, terminal); - - /* - * The command might result in a change of the RAM usage. Validate - * that the preservation is satisfied. - */ - ram.validate_preservation(); - line_editor.reset(); + /** + * Handler for child yield responses, or RAM resource-avail signals + */ + void _handle_yield_response() + { + for (Child *child = _children.first(); child; child = child->next()) + child->try_response_to_resource_request(); } - env.parent().exit(0); + Signal_handler
_yield_response_handler { + _env.ep(), *this, &Main::_handle_yield_response }; + + void _handle_child_exit() + { + Child *next = nullptr; + for (Child *child = _children.first(); child; child = next) { + next = child->next(); + if (child->exited()) { + _children.remove(child); + Genode::destroy(_heap, child); + } + } + } + + Signal_handler
_child_exit_handler { + _env.ep(), *this, &Main::_handle_child_exit }; + + void _handle_yield_broadcast() + { + /* + * Compute argument of yield request to be broadcasted to all + * processes. + */ + size_t amount = 0; + + /* amount needed to reach preservation limit */ + Ram::Status ram_status = _ram.status(); + if (ram_status.avail < ram_status.preserve) + amount += ram_status.preserve - ram_status.avail; + + /* sum of pending resource requests */ + for (Child *child = _children.first(); child; child = child->next()) + amount += child->requested_ram_quota(); + + for (Child *child = _children.first(); child; child = child->next()) + child->yield(amount, true); + } + + Signal_handler
_yield_broadcast_handler { + _env.ep(), *this, &Main::_handle_yield_broadcast }; + + Genode::Attached_rom_dataspace _config { _env, "config" }; + + Xml_node _vfs_config() const + { + try { return _config.xml().sub_node("vfs"); } + catch (Genode::Xml_node::Nonexistent_sub_node) { + Genode::error("missing '' configuration"); + throw; + } + } + + size_t _ram_preservation_from_config() const + { + if (!_config.xml().has_sub_node("preservation")) + return 0; + + return _config.xml().sub_node("preservation") + .attribute_value("name", Genode::Number_of_bytes(0)); + } + + Ram _ram { _env.ram(), _env.ram_session_cap(), _ram_preservation_from_config(), + _yield_broadcast_handler, _yield_response_handler }; + + Heap _heap { _env.ram(), _env.rm() }; + + /* initialize virtual file system */ + Vfs::Dir_file_system _root_dir { _env, _heap, _vfs_config(), + Vfs::global_file_system_factory() }; + + Subsystem_config_registry _subsystem_config_registry { _root_dir, _heap }; + + template + struct Registered : T + { + template + Registered(Command_registry &commands, ARGS &&... args) + : T(args...) { commands.insert(this); } + }; + + /* initialize generic commands */ + Registered _help_command { _commands }; + Registered _kill_command { _commands, _children, _heap }; + Registered _start_command { _commands, _ram, _heap, _env.pd(), + _env.ram(), _env.ram_session_cap(), + _env.rm(), _children, + _subsystem_config_registry, + _yield_response_handler, + _child_exit_handler }; + Registered _status_command { _commands, _ram, _children }; + Registered _yield_command { _commands, _children }; + Registered _ram_command { _commands, _children, _ram }; + + Main(Env &env) : _env(env) + { + _terminal.read_avail_sigh(_terminal_read_avail_handler); + } +}; + + +void Cli_monitor::Main::_handle_terminal_read_avail() +{ + /* supply pending terminal input to line editor */ + while (_terminal.avail() && !_line_editor.completed()) { + char c = 0; + _terminal.read(&c, 1); + _line_editor.submit_input(c); + } + + if (!_line_editor.completed()) + return; + + Command *command = _lookup_command(_command_buf); + if (!command) { + Token cmd_name(_command_buf); + tprintf(_terminal, "Error: unknown command \""); + _terminal.write(cmd_name.start(), cmd_name.len()); + tprintf(_terminal, "\"\n"); + _line_editor.reset(); + return; + } + + /* validate parameters against command meta data */ + Command_line cmd_line(_command_buf, *command); + Token unexpected = cmd_line.unexpected_parameter(); + if (unexpected) { + tprintf(_terminal, "Error: unexpected parameter \""); + _terminal.write(unexpected.start(), unexpected.len()); + tprintf(_terminal, "\"\n"); + _line_editor.reset(); + return; + } + command->execute(cmd_line, _terminal); + + /* + * The command might result in a change of the RAM usage. Validate + * that the preservation is satisfied. + */ + _ram.validate_preservation(); + _line_editor.reset(); } + + +void Component::construct(Genode::Env &env) { static Cli_monitor::Main main(env); } diff --git a/repos/os/src/app/cli_monitor/no_extension.cc b/repos/os/src/app/cli_monitor/no_extension.cc index 112d98ae63..4f09c44bda 100644 --- a/repos/os/src/app/cli_monitor/no_extension.cc +++ b/repos/os/src/app/cli_monitor/no_extension.cc @@ -13,5 +13,5 @@ #include -void init_extension(Command_registry &) { } +void Cli_monitor::init_extension(Command_registry &) { } diff --git a/repos/os/src/app/cli_monitor/ram_command.h b/repos/os/src/app/cli_monitor/ram_command.h index 395fd04b90..476ed0a5e2 100644 --- a/repos/os/src/app/cli_monitor/ram_command.h +++ b/repos/os/src/app/cli_monitor/ram_command.h @@ -17,17 +17,24 @@ /* local includes */ #include -struct Ram_command : Command -{ - Child_registry &_children; +namespace Cli_monitor { struct Ram_command; } - Ram_command(Child_registry &children) + +struct Cli_monitor::Ram_command : Command +{ + Child_registry &_children; + Ram &_ram; + + Parameter _quota_param { "--quota", Parameter::NUMBER, "new RAM quota" }; + Parameter _limit_param { "--limit", Parameter::NUMBER, "on-demand quota limit" }; + + Ram_command(Child_registry &children, Ram &ram) : Command("ram", "set RAM quota of subsystem"), - _children(children) + _children(children), _ram(ram) { - add_parameter(new Parameter("--quota", Parameter::NUMBER, "new RAM quota")); - add_parameter(new Parameter("--limit", Parameter::NUMBER, "on-demand quota limit")); + add_parameter(_quota_param); + add_parameter(_limit_param); } void _set_quota(Terminal::Session &terminal, Child &child, size_t const new_quota) @@ -37,7 +44,7 @@ struct Ram_command : Command if (new_quota > old_quota) { size_t amount = new_quota - old_quota; - size_t const avail = Genode::env()->ram_session()->avail(); + size_t const avail = _ram.avail(); if (amount > avail) { tprintf(terminal, "upgrade of '%s' exceeds available quota of ", child.name().string()); diff --git a/repos/os/src/app/cli_monitor/spec/arm/gdb_prefix.h b/repos/os/src/app/cli_monitor/spec/arm/gdb_prefix.h deleted file mode 100644 index 32b9f79ec0..0000000000 --- a/repos/os/src/app/cli_monitor/spec/arm/gdb_prefix.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * \brief Prefix of the GDB binary - * \author Christian Prochaska - * \date 2013-10-23 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _APP__CLI_MONITOR__SPEC__ARM__GDB_PREFIX_H_ -#define _APP__CLI_MONITOR__SPEC__ARM__GDB_PREFIX_H_ - -static const char *gdb_prefix = "genode-arm-"; - -#endif /* _APP__CLI_MONITOR__SPEC__ARM__GDB_PREFIX_H_ */ diff --git a/repos/os/src/app/cli_monitor/spec/foc/arndale/extension.cc b/repos/os/src/app/cli_monitor/spec/foc/arndale/extension.cc deleted file mode 100644 index 5e42c858d9..0000000000 --- a/repos/os/src/app/cli_monitor/spec/foc/arndale/extension.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * \brief Fiasco.OC on Arndale specific CLI-monitor extensions - * \author Norman Feske - * \author Stefan Kalkowski - * \date 2013-03-18 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* Genode includes */ -#include -#include - -/* local includes */ -#include - -struct Cpufreq_command : Command -{ - Regulator::Connection ®ulator; - - Cpufreq_command(Regulator::Connection &r) - : Command("cpu_frequency", "set/show CPU frequency"), - regulator(r) { } - - void execute(Command_line &cmd, Terminal::Session &terminal) - { - char freq[128]; - freq[0] = 0; - if (cmd.argument(0, freq, sizeof(freq)) == false) { - tprintf(terminal, "Current CPU frequency: %ld Hz\n", - regulator.level()); - return; - } - - unsigned long f = 0; - Genode::ascii_to(freq, f); - tprintf(terminal, "set frequency to %ld Hz\n", f); - regulator.level(f); - } -}; - - -void init_extension(Command_registry &commands) -{ - try { /* only inserts commands if route to regulator session exists */ - static Regulator::Connection reg(Regulator::CLK_CPU); - static Cpufreq_command cpufreq_command(reg); - commands.insert(&cpufreq_command); - } catch (...) { Genode::warning("no regulator session available!"); }; - - static Kdebug_command kdebug_command; - commands.insert(&kdebug_command); - - static Reboot_command reboot_command; - commands.insert(&reboot_command); -} diff --git a/repos/os/src/app/cli_monitor/spec/foc/common.h b/repos/os/src/app/cli_monitor/spec/foc/common.h deleted file mode 100644 index 5a3b140535..0000000000 --- a/repos/os/src/app/cli_monitor/spec/foc/common.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * \brief Fiasco.OC-specific CLI-monitor extensions - * \author Norman Feske - * \date 2013-03-18 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _APP__CLI_MONITOR__SPEC__FOC__COMMON_H_ -#define _APP__CLI_MONITOR__SPEC__FOC__COMMON_H_ - -/* local includes */ -#include -#include -#include - -/* Fiasco includes */ -namespace Fiasco { -#include -#include -} - - -static void clear_host_terminal() -{ - using namespace Fiasco; - - outstring("\e[99S"); /* scroll up */ - outstring("\e[99T"); /* scroll down */ - outstring("\e[199A"); /* move cursor up */ -} - - -struct Kdebug_command : Command -{ - Kdebug_command() : Command("kdebug", "enter kernel debugger (via serial console)") { } - - void execute(Command_line &, Terminal::Session &terminal) - { - using namespace Fiasco; - - /* let kernel debugger detect the screen size */ - enter_kdebug("*#JS"); - - clear_host_terminal(); - enter_kdebug("Entering kernel debugger... Press [?] for help"); - clear_host_terminal(); - } -}; - - -struct Reboot_command : Command -{ - Reboot_command() : Command("reboot", "reboot machine") { } - - void execute(Command_line &, Terminal::Session &terminal) - { - using namespace Fiasco; - - clear_host_terminal(); - enter_kdebug("*#^"); - } -}; - -#endif /* _APP__CLI_MONITOR__SPEC__FOC__COMMON_H_ */ diff --git a/repos/os/src/app/cli_monitor/spec/foc/extension.cc b/repos/os/src/app/cli_monitor/spec/foc/extension.cc deleted file mode 100644 index 7fc2c3c9ad..0000000000 --- a/repos/os/src/app/cli_monitor/spec/foc/extension.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * \brief Fiasco.OC-specific CLI-monitor extensions - * \author Norman Feske - * \date 2013-03-18 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* local includes */ -#include - - -void init_extension(Command_registry &commands) -{ - static Kdebug_command kdebug_command; - commands.insert(&kdebug_command); - - static Reboot_command reboot_command; - commands.insert(&reboot_command); -} diff --git a/repos/os/src/app/cli_monitor/spec/riscv/gdb_prefix.h b/repos/os/src/app/cli_monitor/spec/riscv/gdb_prefix.h deleted file mode 100644 index b2018d469d..0000000000 --- a/repos/os/src/app/cli_monitor/spec/riscv/gdb_prefix.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * \brief Prefix of the GDB binary - * \author Sebastian Sumpf - * \date 2016-02-16 - */ - -/* - * Copyright (C) 2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _APP__CLI_MONITOR__SPEC__RISCV__GDB_PREFIX_H_ -#define _APP__CLI_MONITOR__SPEC__RISCV__GDB_PREFIX_H_ - -static const char *gdb_prefix = "genode-riscv-"; - -#endif /* _APP__CLI_MONITOR__SPEC__RISCV__GDB_PREFIX_H_ */ diff --git a/repos/os/src/app/cli_monitor/spec/x86/gdb_prefix.h b/repos/os/src/app/cli_monitor/spec/x86/gdb_prefix.h deleted file mode 100644 index 71b84890e9..0000000000 --- a/repos/os/src/app/cli_monitor/spec/x86/gdb_prefix.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * \brief Prefix of the GDB binary - * \author Christian Prochaska - * \date 2013-10-23 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _APP__CLI_MONITOR__SPEC__X86__GDB_PREFIX_H_ -#define _APP__CLI_MONITOR__SPEC__X86__GDB_PREFIX_H_ - -static const char *gdb_prefix = "genode-x86-"; - -#endif /* _APP__CLI_MONITOR__SPEC__X86__GDB_PREFIX_H_ */ diff --git a/repos/os/src/app/cli_monitor/start_command.h b/repos/os/src/app/cli_monitor/start_command.h index 610349c35a..73a33f4969 100644 --- a/repos/os/src/app/cli_monitor/start_command.h +++ b/repos/os/src/app/cli_monitor/start_command.h @@ -20,7 +20,10 @@ /* local includes */ #include -class Start_command : public Command +namespace Cli_monitor { class Start_command; } + + +class Cli_monitor::Start_command : public Command { private: @@ -29,6 +32,7 @@ class Start_command : public Command typedef Genode::Dataspace_capability Dataspace_capability; Ram &_ram; + Genode::Allocator &_alloc; Child_registry &_children; Genode::Pd_session &_pd; Genode::Ram_session &_ref_ram; @@ -67,7 +71,7 @@ class Start_command : public Command /* acount for cli_monitor local metadata */ size_t preserve_ram = 100*1024; - if (count * (ram + preserve_ram) > Genode::env()->ram_session()->avail()) { + if (count * (ram + preserve_ram) > _ram.avail()) { tprintf(terminal, "Error: RAM quota exceeds available quota\n"); return; } @@ -108,7 +112,7 @@ class Start_command : public Command Child *child = 0; try { - child = new (Genode::env()->heap()) + child = new (_alloc) Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap, _local_rm, ram, ram_limit, _yield_response_sigh_cap, _exit_sig_cap); @@ -122,7 +126,7 @@ class Start_command : public Command tprintf(terminal, "Error: insufficient memory, need "); tprint_bytes(terminal, ram + Child::DONATED_RAM_QUOTA); tprintf(terminal, ", have "); - tprint_bytes(terminal, Genode::env()->ram_session()->avail()); + tprint_bytes(terminal, _ram.avail()); tprintf(terminal, "\n"); return; } @@ -147,9 +151,15 @@ class Start_command : public Command } } + Parameter _count_param { "--count", Parameter::NUMBER, "number of instances" }; + Parameter _ram_param { "--ram", Parameter::NUMBER, "initial RAM quota" }; + Parameter _ram_limit_param { "--ram-limit", Parameter::NUMBER, "limit for expanding RAM quota" }; + Parameter _verbose_param { "--verbose", Parameter::VOID, "show diagnostics" }; + public: Start_command(Ram &ram, + Genode::Allocator &alloc, Genode::Pd_session &pd, Genode::Ram_session &ref_ram, Genode::Ram_session_capability ref_ram_cap, @@ -160,16 +170,16 @@ class Start_command : public Command Signal_context_capability exit_sig_cap) : Command("start", "create new subsystem"), - _ram(ram), _children(children), _pd(pd), + _ram(ram), _alloc(alloc), _children(children), _pd(pd), _ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _local_rm(local_rm), _subsystem_configs(subsustem_configs), _yield_response_sigh_cap(yield_response_sigh_cap), _exit_sig_cap(exit_sig_cap) { - add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances")); - add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota")); - add_parameter(new Parameter("--ram-limit", Parameter::NUMBER, "limit for expanding RAM quota")); - add_parameter(new Parameter("--verbose", Parameter::VOID, "show diagnostics")); + add_parameter(_count_param); + add_parameter(_ram_param); + add_parameter(_ram_limit_param); + add_parameter(_verbose_param); } void _for_each_argument(Argument_fn const &fn) const override diff --git a/repos/os/src/app/cli_monitor/status_command.h b/repos/os/src/app/cli_monitor/status_command.h index 21a5bc7197..ca871666c1 100644 --- a/repos/os/src/app/cli_monitor/status_command.h +++ b/repos/os/src/app/cli_monitor/status_command.h @@ -18,7 +18,10 @@ #include #include -struct Status_command : Command +namespace Cli_monitor { struct Status_command; } + + +struct Cli_monitor::Status_command : Command { Child_registry &_children; Ram &_ram; diff --git a/repos/os/src/app/cli_monitor/subsystem_config_registry.h b/repos/os/src/app/cli_monitor/subsystem_config_registry.h index 9f00e84e4f..40b7e590cb 100644 --- a/repos/os/src/app/cli_monitor/subsystem_config_registry.h +++ b/repos/os/src/app/cli_monitor/subsystem_config_registry.h @@ -18,7 +18,10 @@ #include #include -class Subsystem_config_registry +namespace Cli_monitor { class Subsystem_config_registry; } + + +class Cli_monitor::Subsystem_config_registry { public: @@ -29,7 +32,8 @@ class Subsystem_config_registry private: - Vfs::File_system &_fs; + Vfs::File_system &_fs; + Genode::Allocator &_alloc; enum { CONFIG_BUF_SIZE = 32*1024 }; char _config_buf[CONFIG_BUF_SIZE]; @@ -58,9 +62,9 @@ class Subsystem_config_registry /** * Constructor */ - Subsystem_config_registry(Vfs::File_system &fs) + Subsystem_config_registry(Vfs::File_system &fs, Genode::Allocator &alloc) : - _fs(fs) + _fs(fs), _alloc(alloc) { } /** @@ -89,7 +93,7 @@ class Subsystem_config_registry Vfs::Directory_service::Open_result const open_result = _fs.open(path.base(), Vfs::Directory_service::OPEN_MODE_RDONLY, - &handle, *Genode::env()->heap()); + &handle, _alloc); Vfs::Vfs_handle::Guard handle_guard(handle); diff --git a/repos/os/src/app/cli_monitor/table.h b/repos/os/src/app/cli_monitor/table.h index 8510facf0d..ac2c28c979 100644 --- a/repos/os/src/app/cli_monitor/table.h +++ b/repos/os/src/app/cli_monitor/table.h @@ -14,8 +14,13 @@ #ifndef _TABLE_H_ #define _TABLE_H_ +#include + +namespace Cli_monitor { template class Table; } + + template -class Table +class Cli_monitor::Table { private: diff --git a/repos/os/src/app/cli_monitor/target.mk b/repos/os/src/app/cli_monitor/target.mk index 5ec078a8a6..41ee20a17e 100644 --- a/repos/os/src/app/cli_monitor/target.mk +++ b/repos/os/src/app/cli_monitor/target.mk @@ -1,16 +1,4 @@ TARGET = cli_monitor SRC_CC = main.cc -LIBS = base cli_monitor config vfs +LIBS = base vfs INC_DIR += $(PRG_DIR) - -ifeq ($(findstring arm, $(SPECS)), arm) -INC_DIR += $(PRG_DIR)/spec/arm -endif - -ifeq ($(findstring x86, $(SPECS)), x86) -INC_DIR += $(PRG_DIR)/spec/x86 -endif - -ifeq ($(findstring riscv, $(SPECS)), riscv) -INC_DIR += $(PRG_DIR)/spec/riscv -endif diff --git a/repos/os/src/app/cli_monitor/yield_command.h b/repos/os/src/app/cli_monitor/yield_command.h index a1c6c94cec..8dcbc83b53 100644 --- a/repos/os/src/app/cli_monitor/yield_command.h +++ b/repos/os/src/app/cli_monitor/yield_command.h @@ -17,17 +17,23 @@ /* local includes */ #include -struct Yield_command : Command +namespace Cli_monitor { struct Yield_command; } + + +struct Cli_monitor::Yield_command : Command { Child_registry &_children; + Parameter _ram_param { "--ram", Parameter::NUMBER, "RAM quota to free" }; + Parameter _greedy_param { "--greedy", Parameter::VOID, "withdraw yielded RAM quota" }; + Yield_command(Child_registry &children) : Command("yield", "instruct subsystem to yield resources"), _children(children) { - add_parameter(new Parameter("--ram", Parameter::NUMBER, "RAM quota to free")); - add_parameter(new Parameter("--greedy", Parameter::VOID, "withdraw yielded RAM quota")); + add_parameter(_ram_param); + add_parameter(_greedy_param); } void _for_each_argument(Argument_fn const &fn) const override