mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
a2a51985f2
commit
f2568856dd
@ -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_ */
|
||||
|
@ -19,89 +19,82 @@
|
||||
#include <os/time_source.h>
|
||||
#include <os/timeout.h>
|
||||
|
||||
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_time_source>;
|
||||
|
||||
::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<Time_source>;
|
||||
|
||||
::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_ */
|
||||
|
@ -61,7 +61,7 @@ class Timer::Session_component : public Genode::Rpc_object<Session>,
|
||||
{
|
||||
_sigh = sigh;
|
||||
if (!sigh.valid())
|
||||
_timeout_scheduler.discard(_timeout);
|
||||
_timeout.discard();
|
||||
}
|
||||
|
||||
unsigned long elapsed_ms() const override {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user