From a7fe4a502d96b3ac33f2753e219bc906a0f7b6d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Mon, 15 Jul 2019 15:06:23 +0200 Subject: [PATCH] rtc_drv: implement set signal handling Issue #3450 --- repos/os/src/drivers/rtc/main.cc | 26 +++++- repos/os/src/test/rtc/main.cc | 131 ++++++++++++++++++------------- 2 files changed, 101 insertions(+), 56 deletions(-) diff --git a/repos/os/src/drivers/rtc/main.cc b/repos/os/src/drivers/rtc/main.cc index 1ac746bd8..82f3e2b6a 100644 --- a/repos/os/src/drivers/rtc/main.cc +++ b/repos/os/src/drivers/rtc/main.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "rtc.h" @@ -35,6 +36,10 @@ struct Rtc::Session_component : public Genode::Rpc_object Signal_context_capability _set_sig_cap { }; + Session_component(Env &env) : _env(env) { } + + virtual ~Session_component() { } + void set_sigh(Signal_context_capability sigh) override { _set_sig_cap = sigh; @@ -47,7 +52,12 @@ struct Rtc::Session_component : public Genode::Rpc_object return ret; } - Session_component(Env &env) : _env(env) { } + void notify_client() + { + if (_set_sig_cap.valid()) { + Signal_transmitter(_set_sig_cap).submit(); + } + } }; @@ -57,11 +67,14 @@ class Rtc::Root : public Genode::Root_component Env &_env; + Registry > _sessions { }; + protected: Session_component *_create_session(const char *) override { - return new (md_alloc()) Session_component(_env); + return new (md_alloc()) + Registered(_sessions, _env); } public: @@ -74,6 +87,13 @@ class Rtc::Root : public Genode::Root_component /* trigger initial RTC read */ Rtc::get_time(_env); } + + void notify_clients() + { + _sessions.for_each([&] (Session_component &session) { + session.notify_client(); + }); + } }; @@ -163,6 +183,8 @@ void Rtc::Main::_handle_update() ts.year = node.attribute_value("year", 2019u); Rtc::set_time(env, ts); + + root.notify_clients(); } diff --git a/repos/os/src/test/rtc/main.cc b/repos/os/src/test/rtc/main.cc index 2cd735a8a..ec59e29b8 100644 --- a/repos/os/src/test/rtc/main.cc +++ b/repos/os/src/test/rtc/main.cc @@ -25,20 +25,88 @@ using namespace Genode; struct Main { - Main(Genode::Env &env) - { - int exit_code = 0; + Env &_env; + Rtc::Connection rtc1 { _env }; + Rtc::Connection rtc2 { _env, "with_label" }; + + Signal_handler
_set_sigh { + _env.ep(), *this, &Main::_handle_set_signal }; + + Rtc::Timestamp _ts { }; + + void _handle_set_signal() + { + Rtc::Timestamp got = rtc1.current_time(); + + Genode::log("Set RTC to: '", _ts, "' got: '", got, + "' (ignoring seconds)"); + + int exit_code = 0; + if ( _ts.year != got.year + || _ts.month != got.month + || _ts.day != got.day + || _ts.hour != got.hour + || _ts.minute != got.minute) { + error("updating RTC failed"); + exit_code = 1; + } + + _parent_exit(exit_code); + } + + Constructible _reporter { }; + + void _test_update() + { + try { + _reporter.construct(_env, "set_rtc"); + _reporter->enabled(true); + + rtc1.set_sigh(_set_sigh); + + Rtc::Timestamp ts = rtc1.current_time(); + ts.year = 2069; + ts.month = 12; + ts.day = 31; + ts.hour = 23; + ts.minute = 55; + ts.second = 0; + + _ts = ts; + + Reporter::Xml_generator xml(*_reporter, [&] () { + xml.attribute("year", ts.year); + xml.attribute("month", ts.month); + xml.attribute("day", ts.day); + xml.attribute("hour", ts.hour); + xml.attribute("minute", ts.minute); + xml.attribute("second", ts.second); + }); + + } catch (...) { + error("could not test RTC update"); + _parent_exit(1); + } + } + + void _parent_exit(int exit_code) + { + Genode::log("--- RTC test finished ---"); + _env.parent().exit(exit_code); + } + + Main(Genode::Env &env) : _env(env) + { Genode::log("--- RTC test started ---"); /* open sessions */ - Rtc::Connection rtc[] = { { env }, { env, "with_label" } }; Timer::Connection timer(env); for (unsigned i = 0; i < 4; ++i) { - Rtc::Timestamp now[] = { rtc[0].current_time(), rtc[1].current_time() }; + Rtc::Timestamp now[] = { rtc1.current_time(), rtc2.current_time() }; - for (unsigned j = 0; j < sizeof(rtc)/sizeof(*rtc); ++j) + for (unsigned j = 0; j < sizeof(now)/sizeof(now[0]); ++j) log("RTC[", j, "]: ", now[j]); timer.msleep(1000); @@ -48,56 +116,11 @@ struct Main Attached_rom_dataspace config_rom { env, "config" }; bool const test_update = config_rom.xml().attribute_value("set_rtc", false); if (test_update) { - try { - Reporter reporter { env, "set_rtc" }; - reporter.enabled(true); - - Rtc::Timestamp ts = rtc[0].current_time(); - ts.year = 2069; - ts.month = 12; - ts.day = 31; - ts.hour = 23; - ts.minute = 55; - ts.second = 0; - - Reporter::Xml_generator xml(reporter, [&] () { - xml.attribute("year", ts.year); - xml.attribute("month", ts.month); - xml.attribute("day", ts.day); - xml.attribute("hour", ts.hour); - xml.attribute("minute", ts.minute); - xml.attribute("second", ts.second); - }); - - /* - * Wait a reasonable amount of time for the RTC update - * to go through. - */ - timer.msleep(3000); - - Rtc::Timestamp got = rtc[0].current_time(); - - Genode::log("Set RTC to: '", ts, "' got: '", got, - "' (ignoring seconds)"); - - if ( ts.year != got.year - || ts.month != got.month - || ts.day != got.day - || ts.hour != got.hour - || ts.minute != got.minute) { - error("updating RTC failed"); - exit_code = 2; - } - - } catch (...) { - error("could not test RTC update"); - exit_code = 1; - } + _test_update(); + return; } - Genode::log("--- RTC test finished ---"); - - env.parent().exit(exit_code); + _parent_exit(0); } };