diff --git a/repos/os/include/os/timeout.h b/repos/os/include/os/timeout.h index 7b19125229..2c67de7c5a 100644 --- a/repos/os/include/os/timeout.h +++ b/repos/os/include/os/timeout.h @@ -31,38 +31,50 @@ namespace Genode { /** * Interface of a time-source multiplexer + * + * Beside 'curr_time()', this abstract interface is used by the Timeout + * implementation only. Users of the timeout framework must schedule and + * discard timeouts via methods of the timeout. */ -struct Genode::Timeout_scheduler +class Genode::Timeout_scheduler { - using Microseconds = Time_source::Microseconds; + public: - /** - * Read out the now time of the scheduler - */ - virtual Microseconds curr_time() const = 0; + using Microseconds = Time_source::Microseconds; - /** - * Add a one-shot timeout to the schedule - * - * \param timeout timeout callback object - * \param duration timeout trigger delay - */ - virtual void schedule_one_shot(Timeout &timeout, Microseconds duration) = 0; + private: - /** - * Add a periodic timeout to the schedule - * - * \param timeout timeout callback object - * \param duration timeout trigger period - */ - virtual void schedule_periodic(Timeout &timeout, Microseconds duration) = 0; + friend Timeout; - /** - * Remove timeout from the scheduler - * - * \param timeout corresponding timeout callback object - */ - virtual void discard(Timeout &timeout) = 0; + /** + * Add a one-shot timeout to the schedule + * + * \param timeout timeout callback object + * \param duration timeout trigger delay + */ + virtual void _schedule_one_shot(Timeout &timeout, Microseconds duration) = 0; + + /** + * Add a periodic timeout to the schedule + * + * \param timeout timeout callback object + * \param duration timeout trigger period + */ + virtual void _schedule_periodic(Timeout &timeout, Microseconds duration) = 0; + + /** + * Remove timeout from the scheduler + * + * \param timeout corresponding timeout callback object + */ + virtual void _discard(Timeout &timeout) = 0; + + public: + + /** + * Read out the now time of the scheduler + */ + virtual Microseconds curr_time() const = 0; }; @@ -118,11 +130,13 @@ class Genode::Timeout : private Noncopyable Timeout(Timeout_scheduler &timeout_scheduler) : _alarm(timeout_scheduler) { } - ~Timeout() { _alarm.timeout_scheduler.discard(*this); } + ~Timeout() { discard(); } void schedule_periodic(Microseconds duration, Handler &handler); void schedule_one_shot(Microseconds duration, Handler &handler); + + void discard(); }; @@ -237,6 +251,17 @@ class Genode::Alarm_timeout_scheduler : private Noncopyable, void handle_timeout(Microseconds curr_time) override; + + /*********************** + ** Timeout_scheduler ** + ***********************/ + + void _schedule_one_shot(Timeout &timeout, Microseconds duration) override; + void _schedule_periodic(Timeout &timeout, Microseconds duration) override; + + void _discard(Timeout &timeout) override { + _alarm_scheduler.discard(&timeout._alarm); } + public: Alarm_timeout_scheduler(Time_source &time_source); @@ -246,14 +271,8 @@ class Genode::Alarm_timeout_scheduler : private Noncopyable, ** Timeout_scheduler ** ***********************/ - void schedule_one_shot(Timeout &timeout, Microseconds duration) override; - void schedule_periodic(Timeout &timeout, Microseconds duration) override; - Microseconds curr_time() const override { return _time_source.curr_time(); } - - void discard(Timeout &timeout) override { - _alarm_scheduler.discard(&timeout._alarm); } }; #endif /* _OS__TIMEOUT_H_ */ diff --git a/repos/os/include/os/timer.h b/repos/os/include/os/timer.h index 3db120dbcb..c74502cb77 100644 --- a/repos/os/include/os/timer.h +++ b/repos/os/include/os/timer.h @@ -19,89 +19,82 @@ #include #include -namespace Genode { class Timer; } +namespace Genode { + class Timer; + class Timer_time_source; +} /** - * Multiplexes a timer session amongst different timeouts + * Implementation helper for 'Timer' + * + * \noapi */ -class Genode::Timer : public Timeout_scheduler +class Genode::Timer_time_source : public Genode::Time_source { private: - class Time_source : public Genode::Time_source + enum { MIN_TIMEOUT_US = 100000 }; + + using Signal_handler = Genode::Signal_handler; + + ::Timer::Session &_session; + Signal_handler _signal_handler; + Timeout_handler *_handler = nullptr; + + void _handle_timeout() { - private: - - enum { MIN_TIMEOUT_US = 100000 }; - - using Signal_handler = - Genode::Signal_handler; - - ::Timer::Session &_session; - Signal_handler _signal_handler; - Timeout_handler *_handler = nullptr; - - void _handle_timeout() - { - if (_handler) { - _handler->handle_timeout(curr_time()); } - } - - public: - - Time_source(::Timer::Session &session, Entrypoint &ep) - : - _session(session), - _signal_handler(ep, *this, &Time_source::_handle_timeout) - { - _session.sigh(_signal_handler); - } - - Microseconds curr_time() const { - return Microseconds(1000ULL * _session.elapsed_ms()); } - - void schedule_timeout(Microseconds duration, - Timeout_handler &handler) - { - if (duration.value < MIN_TIMEOUT_US) { - duration.value = MIN_TIMEOUT_US; } - - if (duration.value > max_timeout().value) { - duration.value = max_timeout().value; } - - _handler = &handler; - _session.trigger_once(duration.value); - } - - Microseconds max_timeout() const { - return Microseconds(~0UL); } - - } _time_source; - - Alarm_timeout_scheduler _timeout_scheduler { _time_source }; + if (_handler) + _handler->handle_timeout(curr_time()); + } public: - Timer(::Timer::Session &session, Entrypoint &ep) - : _time_source(session, ep) { } + Timer_time_source(::Timer::Session &session, Entrypoint &ep) + : + _session(session), + _signal_handler(ep, *this, &Timer_time_source::_handle_timeout) + { + _session.sigh(_signal_handler); + } + + Microseconds curr_time() const { + return Microseconds(1000ULL * _session.elapsed_ms()); } + + void schedule_timeout(Microseconds duration, + Timeout_handler &handler) + { + if (duration.value < MIN_TIMEOUT_US) + duration.value = MIN_TIMEOUT_US; + + if (duration.value > max_timeout().value) + duration.value = max_timeout().value; + + _handler = &handler; + _session.trigger_once(duration.value); + } + + Microseconds max_timeout() const { + return Microseconds(~0UL); } + +}; - /*********************** - ** Timeout_scheduler ** - ***********************/ +/** + * Timer-session based timeout scheduler + * + * Multiplexes a timer session amongst different timeouts. + */ +struct Genode::Timer : private Genode::Timer_time_source, + public Genode::Alarm_timeout_scheduler +{ + using Time_source::Microseconds; - void schedule_periodic(Timeout &timeout, Microseconds duration) override { - _timeout_scheduler.schedule_periodic(timeout, duration); } - - void schedule_one_shot(Timeout &timeout, Microseconds duration) override { - _timeout_scheduler.schedule_one_shot(timeout, duration); } - - Microseconds curr_time() const override { - return _timeout_scheduler.curr_time(); } - - void discard(Timeout &timeout) override { - _timeout_scheduler.discard(timeout); } + Timer(::Timer::Session &session, Entrypoint &ep) + : + Timer_time_source(session, ep), + Alarm_timeout_scheduler(*(Time_source*)this) + { } }; #endif /* _TIMER_H_ */ diff --git a/repos/os/src/drivers/timer/include/session_component.h b/repos/os/src/drivers/timer/include/session_component.h index 0c324e69e3..7efd589f17 100644 --- a/repos/os/src/drivers/timer/include/session_component.h +++ b/repos/os/src/drivers/timer/include/session_component.h @@ -61,7 +61,7 @@ class Timer::Session_component : public Genode::Rpc_object, { _sigh = sigh; if (!sigh.valid()) - _timeout_scheduler.discard(_timeout); + _timeout.discard(); } unsigned long elapsed_ms() const override { diff --git a/repos/os/src/lib/timeout/timeout.cc b/repos/os/src/lib/timeout/timeout.cc index 993ea0996e..4ea048688e 100644 --- a/repos/os/src/lib/timeout/timeout.cc +++ b/repos/os/src/lib/timeout/timeout.cc @@ -25,14 +25,20 @@ void Timeout::schedule_periodic(Microseconds duration, Handler &handler) { _alarm.handler = &handler; _alarm.periodic = true; - _alarm.timeout_scheduler.schedule_periodic(*this, duration); + _alarm.timeout_scheduler._schedule_periodic(*this, duration); } void Timeout::schedule_one_shot(Microseconds duration, Handler &handler) { _alarm.handler = &handler; _alarm.periodic = false; - _alarm.timeout_scheduler.schedule_one_shot(*this, duration); + _alarm.timeout_scheduler._schedule_one_shot(*this, duration); +} + +void Timeout::discard() +{ + _alarm.timeout_scheduler._discard(*this); + _alarm.handler = nullptr; } @@ -82,8 +88,8 @@ Alarm_timeout_scheduler::Alarm_timeout_scheduler(Time_source &time_source) } -void Alarm_timeout_scheduler::schedule_one_shot(Timeout &timeout, - Microseconds duration) +void Alarm_timeout_scheduler::_schedule_one_shot(Timeout &timeout, + Microseconds duration) { _alarm_scheduler.schedule_absolute(&timeout._alarm, _time_source.curr_time().value + @@ -94,8 +100,8 @@ void Alarm_timeout_scheduler::schedule_one_shot(Timeout &timeout, } -void Alarm_timeout_scheduler::schedule_periodic(Timeout &timeout, - Microseconds duration) +void Alarm_timeout_scheduler::_schedule_periodic(Timeout &timeout, + Microseconds duration) { _alarm_scheduler.handle(_time_source.curr_time().value); _alarm_scheduler.schedule(&timeout._alarm, duration.value);