app/cli_monitor: API transition

Besides updating CLI monitor to the new API, the patch removes
Fiasco.OC-specific extensions that remained unused for a long time.

Ref #1987
This commit is contained in:
Norman Feske 2017-01-03 12:52:42 +01:00
parent 7f5e2c2eb2
commit e91170a49c
31 changed files with 428 additions and 625 deletions

View File

@ -78,7 +78,7 @@ struct Launcher::Main
return 0; return 0;
} }
Subsystem_manager _subsystem_manager { _env.ep(), _env.pd(), Subsystem_manager _subsystem_manager { _env,
_ram_preservation(_config.xml()), _ram_preservation(_config.xml()),
_exited_child_handler }; _exited_child_handler };

View File

@ -25,6 +25,7 @@ namespace Launcher {
class Subsystem_manager; class Subsystem_manager;
using Decorator::string_attribute; using Decorator::string_attribute;
using Cli_monitor::Ram;
using namespace Genode; using namespace Genode;
} }
@ -40,12 +41,11 @@ class Launcher::Subsystem_manager
private: private:
Entrypoint &_ep; Env & _env;
Pd_session &_pd; Heap _heap { _env.ram(), _env.rm() };
size_t const _ram_preservation; size_t const _ram_preservation;
struct Child : Child_base, List<Child>::Element struct Child : Cli_monitor::Child_base, List<Child>::Element
{ {
template <typename... ARGS> template <typename... ARGS>
Child(ARGS &&... args) : Child_base(args...) { } Child(ARGS &&... args) : Child_base(args...) { }
@ -60,7 +60,7 @@ class Launcher::Subsystem_manager
} }
Signal_handler<Subsystem_manager> _yield_broadcast_handler = Signal_handler<Subsystem_manager> _yield_broadcast_handler =
{ _ep, *this, &Subsystem_manager::_handle_yield_broadcast }; { _env.ep(), *this, &Subsystem_manager::_handle_yield_broadcast };
void _handle_yield_broadcast() void _handle_yield_broadcast()
{ {
@ -90,7 +90,7 @@ class Launcher::Subsystem_manager
} }
Signal_handler<Subsystem_manager> _resource_avail_handler = Signal_handler<Subsystem_manager> _resource_avail_handler =
{ _ep, *this, &Subsystem_manager::_handle_resource_avail }; { _env.ep(), *this, &Subsystem_manager::_handle_resource_avail };
void _handle_resource_avail() void _handle_resource_avail()
{ {
@ -98,7 +98,7 @@ class Launcher::Subsystem_manager
} }
Signal_handler<Subsystem_manager> _yield_response_handler = Signal_handler<Subsystem_manager> _yield_response_handler =
{ _ep, *this, &Subsystem_manager::_handle_yield_response }; { _env.ep(), *this, &Subsystem_manager::_handle_yield_response };
void _handle_yield_response() void _handle_yield_response()
{ {
@ -107,7 +107,9 @@ class Launcher::Subsystem_manager
Genode::Signal_context_capability _exited_child_sig_cap; 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, _yield_broadcast_handler,
_resource_avail_handler }; _resource_avail_handler };
@ -147,11 +149,11 @@ class Launcher::Subsystem_manager
public: public:
Subsystem_manager(Genode::Entrypoint &ep, Pd_session &pd, Subsystem_manager(Genode::Env & env,
size_t ram_preservation, size_t ram_preservation,
Genode::Signal_context_capability exited_child_sig_cap) 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) _exited_child_sig_cap(exited_child_sig_cap)
{ } { }
@ -172,12 +174,12 @@ class Launcher::Subsystem_manager
Genode::log("starting child '", label.string(), "'"); Genode::log("starting child '", label.string(), "'");
try { try {
Child *child = new (env()->heap()) Child *child = new (_heap)
Child(_ram, label, binary_name.string(), Child(_ram, label, binary_name.string(),
*Genode::env()->pd_session(), _env.pd(),
*Genode::env()->ram_session(), _env.ram(),
Genode::env()->ram_session_cap(), _env.ram_session_cap(),
*Genode::env()->rm_session(), _env.rm(),
ram_config.quantum, ram_config.limit, ram_config.quantum, ram_config.limit,
_yield_broadcast_handler, _yield_broadcast_handler,
_exited_child_sig_cap); _exited_child_sig_cap);
@ -203,7 +205,7 @@ class Launcher::Subsystem_manager
for (Child *c = _children.first(); c; c = c->next()) { for (Child *c = _children.first(); c; c = c->next()) {
if (c->label() == Label(label)) { if (c->label() == Label(label)) {
_children.remove(c); _children.remove(c);
destroy(env()->heap(), c); destroy(_heap, c);
return; return;
} }
} }

View File

@ -27,8 +27,10 @@
/* CLI-monitor includes */ /* CLI-monitor includes */
#include <cli_monitor/ram.h> #include <cli_monitor/ram.h>
namespace Cli_monitor { class Child_base; }
class Child_base : public Genode::Child_policy
class Cli_monitor::Child_base : public Genode::Child_policy
{ {
public: public:

View File

@ -17,15 +17,19 @@
/* Genode includes */ /* Genode includes */
#include <ram_session/connection.h> #include <ram_session/connection.h>
class Ram namespace Cli_monitor { class Ram; }
class Cli_monitor::Ram
{ {
private: private:
typedef Genode::size_t size_t; typedef Genode::size_t size_t;
Genode::Ram_session &_ram;
Genode::Ram_session_capability _ram_cap;
Genode::Lock mutable _lock; 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 _yield_sigh;
Genode::Signal_context_capability _resource_avail_sigh; Genode::Signal_context_capability _resource_avail_sigh;
@ -50,10 +54,13 @@ class Ram
: quota(quota), used(used), avail(avail), preserve(preserve) { } : 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 yield_sigh,
Genode::Signal_context_capability resource_avail_sigh) Genode::Signal_context_capability resource_avail_sigh)
: :
_ram(ram), _ram_cap(ram_cap),
_yield_sigh(yield_sigh), _yield_sigh(yield_sigh),
_resource_avail_sigh(resource_avail_sigh), _resource_avail_sigh(resource_avail_sigh),
_preserve(preserve) _preserve(preserve)
@ -128,10 +135,7 @@ class Ram
throw Transfer_quota_failed(); throw Transfer_quota_failed();
} }
/** size_t avail() const { return _ram.avail(); }
* Return singleton object
*/
static Ram &ram();
}; };
#endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */ #endif /* _INCLUDE__CLI_MONITOR__RAM_H_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +0,0 @@
LIBS += foc_cli_monitor

View File

@ -20,7 +20,10 @@
/* local includes */ /* local includes */
#include <line_editor.h> #include <line_editor.h>
struct Child : Child_base, List<Child>::Element namespace Cli_monitor { struct Child; }
struct Cli_monitor::Child : Child_base, List<Child>::Element
{ {
Argument argument; Argument argument;

View File

@ -20,7 +20,10 @@
/* local includes */ /* local includes */
#include <child.h> #include <child.h>
class Child_registry : public List<Child> namespace Cli_monitor { class Child_registry; }
class Cli_monitor::Child_registry : public List<Child>
{ {
private: private:

View File

@ -16,7 +16,10 @@
#include <line_editor.h> #include <line_editor.h>
class Command_line namespace Cli_monitor { class Command_line; }
class Cli_monitor::Command_line
{ {
private: private:

View File

@ -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 <line_editor.h>
/**
* Initialize and register platform-specific commands
*/
void init_extension(Command_registry &);
#endif /* _EXTENSION_H_ */

View File

@ -17,96 +17,98 @@
/* local includes */ /* local includes */
#include <terminal_util.h> #include <terminal_util.h>
namespace Cli_monitor {
/** /**
* Print rational number with two fractional decimals * Print rational number with two fractional decimals
*/ */
static inline size_t format_number(char *dst, size_t len, size_t const value, 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 quotient, char const *unit)
{ {
size_t const integer = value / quotient; size_t const integer = value / quotient;
size_t const n = snprintf(dst, len, "%ld.", integer); size_t const n = snprintf(dst, len, "%ld.", integer);
size_t const remainder = ((value - (integer * quotient))*100) / quotient; size_t const remainder = ((value - (integer * quotient))*100) / quotient;
if (len == n) return n; if (len == n) return n;
return n + snprintf(dst + n, len - n, "%s%ld%s", return n + snprintf(dst + n, len - n, "%s%ld%s",
remainder < 10 ? "0" : "", remainder, unit); remainder < 10 ? "0" : "", remainder, unit);
} }
/** /**
* Print number of bytes using the best suitable unit * Print number of bytes using the best suitable unit
*/ */
static inline size_t format_bytes(char *dst, size_t len, size_t bytes) static inline size_t format_bytes(char *dst, size_t len, size_t bytes)
{ {
enum { KB = 1024, MB = 1024*KB }; enum { KB = 1024, MB = 1024*KB };
if (bytes > MB) if (bytes > MB)
return format_number(dst, len, bytes, MB, " MiB"); return format_number(dst, len, bytes, MB, " MiB");
if (bytes > KB) if (bytes > KB)
return format_number(dst, len, bytes, KB, " KiB"); return format_number(dst, len, bytes, KB, " KiB");
return snprintf(dst, len, "%ld bytes", bytes); return snprintf(dst, len, "%ld bytes", bytes);
} }
/** /**
* Print number in MiB, without unit * Print number in MiB, without unit
*/ */
static inline size_t format_mib(char *dst, size_t len, size_t bytes) static inline size_t format_mib(char *dst, size_t len, size_t bytes)
{ {
enum { KB = 1024, MB = 1024*KB }; enum { KB = 1024, MB = 1024*KB };
return format_number(dst, len, bytes, MB , ""); return format_number(dst, len, bytes, MB , "");
} }
static inline size_t format_bytes(size_t bytes) static inline size_t format_bytes(size_t bytes)
{ {
char buf[128]; char buf[128];
return format_bytes(buf, sizeof(buf), bytes); return format_bytes(buf, sizeof(buf), bytes);
} }
static inline size_t format_mib(size_t bytes) static inline size_t format_mib(size_t bytes)
{ {
char buf[128]; char buf[128];
return format_mib(buf, sizeof(buf), bytes); return format_mib(buf, sizeof(buf), bytes);
} }
static inline void tprint_bytes(Terminal::Session &terminal, size_t bytes) static inline void tprint_bytes(Terminal::Session &terminal, size_t bytes)
{ {
char buf[128]; char buf[128];
format_bytes(buf, sizeof(buf), bytes); format_bytes(buf, sizeof(buf), bytes);
Terminal::tprintf(terminal, "%s", buf); Terminal::tprintf(terminal, "%s", buf);
} }
static inline void tprint_mib(Terminal::Session &terminal, size_t bytes) static inline void tprint_mib(Terminal::Session &terminal, size_t bytes)
{ {
char buf[128]; char buf[128];
format_mib(buf, sizeof(buf), bytes); format_mib(buf, sizeof(buf), bytes);
Terminal::tprintf(terminal, "%s", buf); Terminal::tprintf(terminal, "%s", buf);
} }
static inline void tprint_status_bytes(Terminal::Session &terminal, static inline void tprint_status_bytes(Terminal::Session &terminal,
char const *label, size_t bytes) char const *label, size_t bytes)
{ {
Terminal::tprintf(terminal, label); Terminal::tprintf(terminal, label);
tprint_bytes(terminal, bytes); tprint_bytes(terminal, bytes);
Terminal::tprintf(terminal, "\n"); Terminal::tprintf(terminal, "\n");
} }
static void tprint_padding(Terminal::Session &terminal, size_t pad, char c = ' ') static void tprint_padding(Terminal::Session &terminal, size_t pad, char c = ' ')
{ {
char const buf[2] = { c, 0 }; char const buf[2] = { c, 0 };
for (unsigned i = 0; i < pad; i++) for (unsigned i = 0; i < pad; i++)
Terminal::tprintf(terminal, buf); Terminal::tprintf(terminal, buf);
}
} }
#endif /* _FORMAT_UTIL_H_ */ #endif /* _FORMAT_UTIL_H_ */

View File

@ -14,7 +14,10 @@
#ifndef _HELP_COMMAND_H_ #ifndef _HELP_COMMAND_H_
#define _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") { } Help_command() : Command("help", "brief help information") { }

View File

@ -17,23 +17,29 @@
/* local includes */ /* local includes */
#include <child_registry.h> #include <child_registry.h>
struct Kill_command : Command namespace Cli_monitor { struct Kill_command; }
struct Cli_monitor::Kill_command : Command
{ {
Child_registry &_children; Child_registry &_children;
Genode::Allocator &_alloc;
Parameter _kill_all_param { "--all", Parameter::VOID, "kill all subsystems" };
void _destroy_child(Child *child, Terminal::Session &terminal) void _destroy_child(Child *child, Terminal::Session &terminal)
{ {
tprintf(terminal, "destroying subsystem '%s'\n", child->name().string()); tprintf(terminal, "destroying subsystem '%s'\n", child->name().string());
_children.remove(child); _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"), Command("kill", "destroy subsystem"), _children(children), _alloc(alloc)
_children(children)
{ {
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 void _for_each_argument(Argument_fn const &fn) const override

View File

@ -16,6 +16,7 @@
/* Genode includes */ /* Genode includes */
#include <base/printf.h> #include <base/printf.h>
#include <base/registry.h>
#include <terminal_session/connection.h> #include <terminal_session/connection.h>
#include <util/string.h> #include <util/string.h>
#include <util/list.h> #include <util/list.h>
@ -23,17 +24,33 @@
#include <util/misc_math.h> #include <util/misc_math.h>
#include <base/snprintf.h> #include <base/snprintf.h>
using Genode::List; namespace Cli_monitor {
using Genode::max;
using Genode::strlen; using Genode::Registry;
using Genode::strncpy; using Genode::List;
using Genode::snprintf; using Genode::max;
using Genode::strcmp; using Genode::strlen;
using Genode::size_t; using Genode::strncpy;
using Genode::off_t; 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<Scanner_policy> Token;
}
struct Completable struct Cli_monitor::Completable
{ {
typedef Genode::String<64> Name; typedef Genode::String<64> Name;
typedef Genode::String<160> Short_help; typedef Genode::String<160> Short_help;
@ -52,7 +69,7 @@ struct Completable
/** /**
* Representation of normal command-line argument * Representation of normal command-line argument
*/ */
struct Argument : Completable struct Cli_monitor::Argument : Completable
{ {
Argument(char const *name, char const *short_help) Argument(char const *name, char const *short_help)
: Completable(name, short_help) { } : Completable(name, short_help) { }
@ -64,7 +81,7 @@ struct Argument : Completable
/** /**
* Representation of a parameter of the form '--tag value' * Representation of a parameter of the form '--tag value'
*/ */
struct Parameter : List<Parameter>::Element, Completable struct Cli_monitor::Parameter : List<Parameter>::Element, Completable
{ {
enum Type { IDENT, NUMBER, VOID }; enum Type { IDENT, NUMBER, VOID };
@ -89,13 +106,10 @@ struct Parameter : List<Parameter>::Element, Completable
}; };
struct Command_line;
/** /**
* Representation of a command that can have arguments and parameters * Representation of a command that can have arguments and parameters
*/ */
struct Command : List<Command>::Element, Completable struct Cli_monitor::Command : List<Command>::Element, Completable
{ {
List<Parameter> _parameters; List<Parameter> _parameters;
@ -110,7 +124,7 @@ struct Command : List<Command>::Element, Completable
Command(char const *name, char const *short_help) Command(char const *name, char const *short_help)
: Completable(name, 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 ""; } char const *name_suffix() const { return ""; }
@ -141,13 +155,13 @@ struct Command : List<Command>::Element, Completable
}; };
struct Command_registry : List<Command> { }; struct Cli_monitor::Command_registry : List<Command> { };
/** /**
* Scanner policy that accepts '-', '.' and '_' as valid identifier characters * 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) static bool identifier_char(char c, unsigned i)
{ {
@ -157,13 +171,10 @@ struct Scanner_policy
}; };
typedef Genode::Token<Scanner_policy> Token;
/** /**
* State machine used for sequentially parsing command-line arguments * State machine used for sequentially parsing command-line arguments
*/ */
struct Argument_tracker struct Cli_monitor::Argument_tracker
{ {
private: private:
@ -288,7 +299,7 @@ struct Argument_tracker
/** /**
* Editing and completion logic * Editing and completion logic
*/ */
class Line_editor class Cli_monitor::Line_editor
{ {
private: private:
@ -482,7 +493,7 @@ class Line_editor
&& strlen(curr->name()) == tag.len()) && strlen(curr->name()) == tag.len())
return curr; return curr;
} }
return 0; return nullptr;
} }
Command *_lookup_matching_command() Command *_lookup_matching_command()
@ -492,7 +503,7 @@ class Line_editor
if (strcmp(cmd.start(), curr->name().string(), cmd.len()) == 0 if (strcmp(cmd.start(), curr->name().string(), cmd.len()) == 0
&& _cursor_pos > cmd.len()) && _cursor_pos > cmd.len())
return curr; return curr;
return 0; return nullptr;
} }
template <typename T> template <typename T>

View File

@ -12,8 +12,8 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <os/config.h> #include <base/attached_rom_dataspace.h>
#include <cap_session/connection.h> #include <base/registry.h>
#include <vfs/file_system_factory.h> #include <vfs/file_system_factory.h>
#include <vfs/dir_file_system.h> #include <vfs/dir_file_system.h>
#include <base/component.h> #include <base/component.h>
@ -25,7 +25,6 @@
#include <line_editor.h> #include <line_editor.h>
#include <command_line.h> #include <command_line.h>
#include <format_util.h> #include <format_util.h>
#include <extension.h>
#include <status_command.h> #include <status_command.h>
#include <kill_command.h> #include <kill_command.h>
#include <start_command.h> #include <start_command.h>
@ -33,12 +32,10 @@
#include <yield_command.h> #include <yield_command.h>
#include <ram_command.h> #include <ram_command.h>
using Genode::Xml_node; namespace Cli_monitor {
struct Main;
inline void *operator new (__SIZE_TYPE__ size) using namespace Genode;
{
return Genode::env()->heap()->alloc(size);
} }
@ -46,186 +43,187 @@ inline void *operator new (__SIZE_TYPE__ size)
** Main program ** ** Main program **
******************/ ******************/
static inline Command *lookup_command(char const *buf, Command_registry &registry) struct Cli_monitor::Main
{ {
Token token(buf); Genode::Env &_env;
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;
}
Terminal::Connection _terminal { _env };
static size_t ram_preservation_from_config() Command_registry _commands;
{
Genode::Number_of_bytes ram_preservation = 0;
try {
Genode::Xml_node node =
Genode::config()->xml_node().sub_node("preservation");
if (node.attribute("name").has_value("RAM")) Child_registry _children;
node.attribute("quantum").value(&ram_preservation);
} catch (...) { }
return ram_preservation; Command *_lookup_command(char const *buf)
} {
Token token(buf);
for (Command *curr = _commands.first(); curr; curr = curr->next())
static Genode::Xml_node vfs_config() if (strcmp(token.start(), curr->name().string(), token.len()) == 0
{ && strlen(curr->name().string()) == token.len())
try { return Genode::config()->xml_node().sub_node("vfs"); } return curr;
catch (Genode::Xml_node::Nonexistent_sub_node) { return 0;
Genode::error("missing '<vfs>' configuration");
throw;
} }
}
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 }; enum { COMMAND_MAX_LEN = 1000 };
static char buf[COMMAND_MAX_LEN]; char _command_buf[COMMAND_MAX_LEN];
static Line_editor line_editor("genode> ", buf, sizeof(buf), terminal, commands); 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 */ Signal_handler<Main> _terminal_read_avail_handler {
Genode::Signal signal = sig_rec.wait_for_signal(); _env.ep(), *this, &Main::_handle_terminal_read_avail };
if (signal.context() == &read_avail_sig_ctx) { /**
* Handler for child yield responses, or RAM resource-avail signals
/* supply pending terminal input to line editor */ */
while (terminal.avail() && !line_editor.completed()) { void _handle_yield_response()
char c; {
terminal.read(&c, 1); for (Child *child = _children.first(); child; child = child->next())
line_editor.submit_input(c); child->try_response_to_resource_request();
}
}
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();
} }
env.parent().exit(0); Signal_handler<Main> _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<Main> _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<Main> _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 '<vfs>' 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 <typename T>
struct Registered : T
{
template <typename... ARGS>
Registered(Command_registry &commands, ARGS &&... args)
: T(args...) { commands.insert(this); }
};
/* initialize generic commands */
Registered<Help_command> _help_command { _commands };
Registered<Kill_command> _kill_command { _commands, _children, _heap };
Registered<Start_command> _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> _status_command { _commands, _ram, _children };
Registered<Yield_command> _yield_command { _commands, _children };
Registered<Ram_command> _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); }

View File

@ -13,5 +13,5 @@
#include <extension.h> #include <extension.h>
void init_extension(Command_registry &) { } void Cli_monitor::init_extension(Command_registry &) { }

View File

@ -17,17 +17,24 @@
/* local includes */ /* local includes */
#include <child_registry.h> #include <child_registry.h>
struct Ram_command : Command namespace Cli_monitor { struct Ram_command; }
{
Child_registry &_children;
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"), 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(_quota_param);
add_parameter(new Parameter("--limit", Parameter::NUMBER, "on-demand quota limit")); add_parameter(_limit_param);
} }
void _set_quota(Terminal::Session &terminal, Child &child, size_t const new_quota) 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) { if (new_quota > old_quota) {
size_t amount = 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) { if (amount > avail) {
tprintf(terminal, "upgrade of '%s' exceeds available quota of ", tprintf(terminal, "upgrade of '%s' exceeds available quota of ",
child.name().string()); child.name().string());

View File

@ -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_ */

View File

@ -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 <regulator_session/connection.h>
#include <util/string.h>
/* local includes */
#include <common.h>
struct Cpufreq_command : Command
{
Regulator::Connection &regulator;
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);
}

View File

@ -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 <extension.h>
#include <terminal_util.h>
#include <command_line.h>
/* Fiasco includes */
namespace Fiasco {
#include <l4/sys/kdebug.h>
#include <l4/sys/ipc.h>
}
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_ */

View File

@ -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 <common.h>
void init_extension(Command_registry &commands)
{
static Kdebug_command kdebug_command;
commands.insert(&kdebug_command);
static Reboot_command reboot_command;
commands.insert(&reboot_command);
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -20,7 +20,10 @@
/* local includes */ /* local includes */
#include <subsystem_config_registry.h> #include <subsystem_config_registry.h>
class Start_command : public Command namespace Cli_monitor { class Start_command; }
class Cli_monitor::Start_command : public Command
{ {
private: private:
@ -29,6 +32,7 @@ class Start_command : public Command
typedef Genode::Dataspace_capability Dataspace_capability; typedef Genode::Dataspace_capability Dataspace_capability;
Ram &_ram; Ram &_ram;
Genode::Allocator &_alloc;
Child_registry &_children; Child_registry &_children;
Genode::Pd_session &_pd; Genode::Pd_session &_pd;
Genode::Ram_session &_ref_ram; Genode::Ram_session &_ref_ram;
@ -67,7 +71,7 @@ class Start_command : public Command
/* acount for cli_monitor local metadata */ /* acount for cli_monitor local metadata */
size_t preserve_ram = 100*1024; 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"); tprintf(terminal, "Error: RAM quota exceeds available quota\n");
return; return;
} }
@ -108,7 +112,7 @@ class Start_command : public Command
Child *child = 0; Child *child = 0;
try { try {
child = new (Genode::env()->heap()) child = new (_alloc)
Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap, Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap,
_local_rm, ram, ram_limit, _local_rm, ram, ram_limit,
_yield_response_sigh_cap, _exit_sig_cap); _yield_response_sigh_cap, _exit_sig_cap);
@ -122,7 +126,7 @@ class Start_command : public Command
tprintf(terminal, "Error: insufficient memory, need "); tprintf(terminal, "Error: insufficient memory, need ");
tprint_bytes(terminal, ram + Child::DONATED_RAM_QUOTA); tprint_bytes(terminal, ram + Child::DONATED_RAM_QUOTA);
tprintf(terminal, ", have "); tprintf(terminal, ", have ");
tprint_bytes(terminal, Genode::env()->ram_session()->avail()); tprint_bytes(terminal, _ram.avail());
tprintf(terminal, "\n"); tprintf(terminal, "\n");
return; 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: public:
Start_command(Ram &ram, Start_command(Ram &ram,
Genode::Allocator &alloc,
Genode::Pd_session &pd, Genode::Pd_session &pd,
Genode::Ram_session &ref_ram, Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap, Genode::Ram_session_capability ref_ram_cap,
@ -160,16 +170,16 @@ class Start_command : public Command
Signal_context_capability exit_sig_cap) Signal_context_capability exit_sig_cap)
: :
Command("start", "create new subsystem"), 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), _ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _local_rm(local_rm),
_subsystem_configs(subsustem_configs), _subsystem_configs(subsustem_configs),
_yield_response_sigh_cap(yield_response_sigh_cap), _yield_response_sigh_cap(yield_response_sigh_cap),
_exit_sig_cap(exit_sig_cap) _exit_sig_cap(exit_sig_cap)
{ {
add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances")); add_parameter(_count_param);
add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota")); add_parameter(_ram_param);
add_parameter(new Parameter("--ram-limit", Parameter::NUMBER, "limit for expanding RAM quota")); add_parameter(_ram_limit_param);
add_parameter(new Parameter("--verbose", Parameter::VOID, "show diagnostics")); add_parameter(_verbose_param);
} }
void _for_each_argument(Argument_fn const &fn) const override void _for_each_argument(Argument_fn const &fn) const override

View File

@ -18,7 +18,10 @@
#include <table.h> #include <table.h>
#include <child_registry.h> #include <child_registry.h>
struct Status_command : Command namespace Cli_monitor { struct Status_command; }
struct Cli_monitor::Status_command : Command
{ {
Child_registry &_children; Child_registry &_children;
Ram &_ram; Ram &_ram;

View File

@ -18,7 +18,10 @@
#include <vfs/file_system.h> #include <vfs/file_system.h>
#include <vfs/vfs_handle.h> #include <vfs/vfs_handle.h>
class Subsystem_config_registry namespace Cli_monitor { class Subsystem_config_registry; }
class Cli_monitor::Subsystem_config_registry
{ {
public: public:
@ -29,7 +32,8 @@ class Subsystem_config_registry
private: private:
Vfs::File_system &_fs; Vfs::File_system &_fs;
Genode::Allocator &_alloc;
enum { CONFIG_BUF_SIZE = 32*1024 }; enum { CONFIG_BUF_SIZE = 32*1024 };
char _config_buf[CONFIG_BUF_SIZE]; char _config_buf[CONFIG_BUF_SIZE];
@ -58,9 +62,9 @@ class Subsystem_config_registry
/** /**
* Constructor * 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 = Vfs::Directory_service::Open_result const open_result =
_fs.open(path.base(), _fs.open(path.base(),
Vfs::Directory_service::OPEN_MODE_RDONLY, Vfs::Directory_service::OPEN_MODE_RDONLY,
&handle, *Genode::env()->heap()); &handle, _alloc);
Vfs::Vfs_handle::Guard handle_guard(handle); Vfs::Vfs_handle::Guard handle_guard(handle);

View File

@ -14,8 +14,13 @@
#ifndef _TABLE_H_ #ifndef _TABLE_H_
#define _TABLE_H_ #define _TABLE_H_
#include <terminal_session/terminal_session.h>
namespace Cli_monitor { template <typename TI> class Table; }
template <typename TI> template <typename TI>
class Table class Cli_monitor::Table
{ {
private: private:

View File

@ -1,16 +1,4 @@
TARGET = cli_monitor TARGET = cli_monitor
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base cli_monitor config vfs LIBS = base vfs
INC_DIR += $(PRG_DIR) 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

View File

@ -17,17 +17,23 @@
/* local includes */ /* local includes */
#include <child_registry.h> #include <child_registry.h>
struct Yield_command : Command namespace Cli_monitor { struct Yield_command; }
struct Cli_monitor::Yield_command : Command
{ {
Child_registry &_children; 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) Yield_command(Child_registry &children)
: :
Command("yield", "instruct subsystem to yield resources"), Command("yield", "instruct subsystem to yield resources"),
_children(children) _children(children)
{ {
add_parameter(new Parameter("--ram", Parameter::NUMBER, "RAM quota to free")); add_parameter(_ram_param);
add_parameter(new Parameter("--greedy", Parameter::VOID, "withdraw yielded RAM quota")); add_parameter(_greedy_param);
} }
void _for_each_argument(Argument_fn const &fn) const override void _for_each_argument(Argument_fn const &fn) const override