Consolidate timer connections at Init

This commit is contained in:
Ehmry - 2019-09-18 11:50:38 +02:00
parent 22164d72e6
commit 8f19fa4143
3 changed files with 39 additions and 54 deletions

View File

@ -28,17 +28,17 @@ class Init::Heartbeat : Genode::Noncopyable
Env &_env; Env &_env;
Genode::Timeout_scheduler &_timer;
Child_registry &_children; Child_registry &_children;
Report_update_trigger &_report_update_trigger; Report_update_trigger &_report_update_trigger;
Constructible<Timer::Connection> _timer { };
uint64_t _rate_ms = 0; uint64_t _rate_ms = 0;
Signal_handler<Heartbeat> _timer_handler; Constructible<Timer::Periodic_timeout<Heartbeat>> _timer_handler { };
void _handle_timer() void _handle_timer(Genode::Duration)
{ {
bool any_skipped_heartbeats = false; bool any_skipped_heartbeats = false;
@ -56,22 +56,22 @@ class Init::Heartbeat : Genode::Noncopyable
public: public:
Heartbeat(Env &env, Child_registry &children, Heartbeat(Env &env, Genode::Timeout_scheduler &timer,
Child_registry &children,
Report_update_trigger &report_update_trigger) Report_update_trigger &report_update_trigger)
: :
_env(env), _children(children), _env(env), _timer(timer), _children(children),
_report_update_trigger(report_update_trigger), _report_update_trigger(report_update_trigger)
_timer_handler(_env.ep(), *this, &Heartbeat::_handle_timer)
{ } { }
void apply_config(Xml_node config) void apply_config(Xml_node config)
{ {
bool const enabled = config.has_sub_node("heartbeat"); bool const enabled = config.has_sub_node("heartbeat");
_timer.conditional(enabled, _env);
if (!enabled) { if (!enabled) {
_rate_ms = 0; _rate_ms = 0;
if (_timer_handler.constructed())
_timer_handler.destruct();
return; return;
} }
@ -79,9 +79,13 @@ class Init::Heartbeat : Genode::Noncopyable
config.sub_node("heartbeat").attribute_value("rate_ms", 1000UL); config.sub_node("heartbeat").attribute_value("rate_ms", 1000UL);
if (rate_ms != _rate_ms) { if (rate_ms != _rate_ms) {
if (_timer_handler.constructed())
_timer_handler.destruct();
_rate_ms = rate_ms; _rate_ms = rate_ms;
_timer->sigh(_timer_handler); _timer_handler.construct(
_timer->trigger_periodic(_rate_ms*1000); _timer, *this, &Heartbeat::_handle_timer,
Microseconds{_rate_ms*1000});
} }
} }
}; };

View File

@ -34,6 +34,8 @@ struct Init::Main : State_reporter::Producer,
Registry<Routed_service> _child_services { }; Registry<Routed_service> _child_services { };
Child_registry _children { }; Child_registry _children { };
Timer::Connection _timer { _env };
Heap _heap { _env.ram(), _env.rm() }; Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
@ -138,9 +140,9 @@ struct Init::Main : State_reporter::Producer,
*/ */
Cap_quota default_caps() override { return _default_caps; } Cap_quota default_caps() override { return _default_caps; }
State_reporter _state_reporter { _env, *this }; State_reporter _state_reporter { _env, _timer, *this };
Heartbeat _heartbeat { _env, _children, _state_reporter }; Heartbeat _heartbeat { _env, _timer, _children, _state_reporter };
Signal_handler<Main> _resource_avail_handler { Signal_handler<Main> _resource_avail_handler {
_env.ep(), *this, &Main::_handle_resource_avail }; _env.ep(), *this, &Main::_handle_resource_avail };

View File

@ -37,6 +37,8 @@ class Init::State_reporter : public Report_update_trigger
Env &_env; Env &_env;
Genode::Timeout_scheduler &_timer;
Producer &_producer; Producer &_producer;
Constructible<Reporter> _reporter { }; Constructible<Reporter> _reporter { };
@ -54,24 +56,13 @@ class Init::State_reporter : public Report_update_trigger
typedef String<64> Version; typedef String<64> Version;
Version _version { }; Version _version { };
Constructible<Timer::Connection> _timer { }; Constructible<Timer::Periodic_timeout<State_reporter>> _timer_periodic { };
Constructible<Timer::Connection> _timer_periodic { };
Signal_handler<State_reporter> _timer_handler { Timer::One_shot_timeout<State_reporter> _timer_one_shot {
_env.ep(), *this, &State_reporter::_handle_timer }; _timer, *this, &State_reporter::_handle_timer };
Signal_handler<State_reporter> _timer_periodic_handler { void _handle_timer(Genode::Duration)
_env.ep(), *this, &State_reporter::_handle_timer };
Signal_handler<State_reporter> _immediate_handler {
_env.ep(), *this, &State_reporter::_handle_timer };
bool _scheduled = false;
void _handle_timer()
{ {
_scheduled = false;
try { try {
Reporter::Xml_generator xml(*_reporter, [&] () { Reporter::Xml_generator xml(*_reporter, [&] () {
@ -96,9 +87,9 @@ class Init::State_reporter : public Report_update_trigger
public: public:
State_reporter(Env &env, Producer &producer) State_reporter(Env &env, Genode::Timeout_scheduler &timer, Producer &producer)
: :
_env(env), _producer(producer) _env(env), _timer(timer), _producer(producer)
{ } { }
void apply_config(Xml_node config) void apply_config(Xml_node config)
@ -134,13 +125,8 @@ class Init::State_reporter : public Report_update_trigger
trigger_update = true; trigger_update = true;
} }
if (_report_delay_ms) { if (_report_delay_ms)
if (!_timer.constructed()) {
_timer.construct(_env);
_timer->sigh(_timer_handler);
}
trigger_update = true; trigger_update = true;
}
if (trigger_update) if (trigger_update)
trigger_report_update(); trigger_report_update();
@ -162,35 +148,28 @@ class Init::State_reporter : public Report_update_trigger
bool const period_changed = (_report_period_ms != period_ms); bool const period_changed = (_report_period_ms != period_ms);
bool const report_periodically = _report_detail->child_ram() bool const report_periodically = _report_detail->child_ram()
|| _report_detail->child_caps(); || _report_detail->child_caps();
_report_period_ms = report_periodically ? period_ms : 0;
if ((!report_periodically || period_changed) && _timer_periodic.constructed())
_timer_periodic.destruct();
if (report_periodically && !_timer_periodic.constructed()) { if (report_periodically && !_timer_periodic.constructed()) {
_timer_periodic.construct(_env); _timer_periodic.construct(
_timer_periodic->sigh(_timer_periodic_handler); _timer, *this, &State_reporter::_handle_timer,
} Genode::Microseconds(_report_period_ms * 1000));
if (!report_periodically && _timer_periodic.constructed()) {
_report_period_ms = 0;
_timer_periodic.destruct();
}
if (period_changed && _timer_periodic.constructed()) {
_report_period_ms = period_ms;
_timer_periodic->trigger_periodic(1000*_report_period_ms);
} }
} }
void trigger_report_update() override void trigger_report_update() override
{ {
if (!_scheduled && _timer.constructed() && _report_delay_ms) { if (_report_delay_ms && !_timer_one_shot.scheduled())
_timer->trigger_once(_report_delay_ms*1000); _timer_one_shot.schedule(Genode::Microseconds{_report_delay_ms*1000});
_scheduled = true;
}
} }
void trigger_immediate_report_update() override void trigger_immediate_report_update() override
{ {
if (_report_delay_ms) if (_report_delay_ms)
Signal_transmitter(_immediate_handler).submit(); _timer_one_shot.schedule(Genode::Microseconds{_report_delay_ms*1000});
} }
}; };