timeout: rework timeout framework

* get rid of alarm abstraction
* get rid of Timeout::Time type
* get rid of pointer arguments
* get rid of _discard_timeout indirection
* get rid of 65th bit in stored time values
* get rid of Timeout_scheduler interface
* get rid of uninitialized deadlines
* get rid of default arguments
* get rid of Timeout::_periodic
* get rid of Timeout::Raw
* use list abstraction
* only one interface for timeout handlers
* rework locking scheme to be smp safe
* move all method definitions to CC file
* name mutexes more accurate
* fix when & how to set time-source timeout
* fix deadlocks

Fixes #3884
This commit is contained in:
Martin Stein
2020-09-11 15:04:40 +02:00
committed by Christian Helmuth
parent 9e5d479d03
commit 7feea78991
26 changed files with 682 additions and 825 deletions

View File

@ -20,8 +20,8 @@
using namespace Genode;
void Timer::Time_source::schedule_timeout(Genode::Microseconds duration,
Timeout_handler &handler)
void Timer::Time_source::set_timeout(Genode::Microseconds duration,
Genode::Timeout_handler &handler)
{
unsigned long const ticks = (1ULL * duration.value * TICKS_PER_MS) / 1000;
_handler = &handler;

View File

@ -71,7 +71,7 @@ class Timer::Time_source : private Genode::Attached_mmio,
*************************/
Genode::Duration curr_time() override;
void schedule_timeout(Genode::Microseconds duration, Timeout_handler &handler) override;
void set_timeout(Genode::Microseconds, Genode::Timeout_handler &) override;
Genode::Microseconds max_timeout() const override { return _max_timeout; };
};

View File

@ -17,8 +17,8 @@
using namespace Genode;
void Timer::Time_source::schedule_timeout(Genode::Microseconds duration,
Timeout_handler &handler)
void Timer::Time_source::set_timeout(Genode::Microseconds duration,
Timeout_handler &handler)
{
_handler = &handler;

View File

@ -68,8 +68,8 @@ class Timer::Time_source : private Genode::Attached_mmio,
*************************/
Genode::Duration curr_time() override;
void schedule_timeout(Genode::Microseconds duration,
Timeout_handler &handler) override;
void set_timeout(Genode::Microseconds duration,
Genode::Timeout_handler &handler) override;
Genode::Microseconds max_timeout() const override;
};

View File

@ -31,8 +31,8 @@ class Timer::Root_component : public Genode::Root_component<Session_component>
enum { MIN_TIMEOUT_US = 1000 };
Time_source _time_source;
Genode::Alarm_timeout_scheduler _timeout_scheduler;
Time_source _time_source;
Genode::Timeout_scheduler _timeout_scheduler;
/********************

View File

@ -34,7 +34,7 @@ namespace Timer {
class Timer::Session_component : public Genode::Rpc_object<Session>,
private Genode::List<Session_component>::Element,
private Genode::Timeout::Handler
private Genode::Timeout_handler
{
private:
@ -47,6 +47,11 @@ class Timer::Session_component : public Genode::Rpc_object<Session>,
uint64_t const _init_time_us =
_timeout_scheduler.curr_time().trunc_to_plain_us().value;
/*********************
** Timeout_handler **
*********************/
void handle_timeout(Duration) override {
Genode::Signal_transmitter(_sigh).submit(); }

View File

@ -24,6 +24,8 @@ namespace Timer {
using Genode::Microseconds;
using Genode::Duration;
using Genode::Timeout_handler;
class Threaded_time_source;
}
@ -31,6 +33,10 @@ namespace Timer {
class Timer::Threaded_time_source : public Genode::Time_source,
protected Genode::Thread
{
public:
enum Result_of_wait_for_irq { IRQ_TRIGGERED, CANCELLED };
private:
struct Irq_dispatcher : Genode::Interface
@ -52,7 +58,7 @@ class Timer::Threaded_time_source : public Genode::Time_source,
public:
Timeout_handler *handler = nullptr;
Timeout_handler *handler = nullptr;
Threaded_time_source &ts;
Irq_dispatcher_component(Threaded_time_source &ts) : ts(ts) { }
@ -76,7 +82,7 @@ class Timer::Threaded_time_source : public Genode::Time_source,
Genode::Capability<Irq_dispatcher> _irq_dispatcher_cap;
virtual void _wait_for_irq() = 0;
virtual Result_of_wait_for_irq _wait_for_irq() = 0;
/***********************
** Thread_deprecated **
@ -85,8 +91,9 @@ class Timer::Threaded_time_source : public Genode::Time_source,
void entry() override
{
while (true) {
_wait_for_irq();
_irq_dispatcher_cap.call<Irq_dispatcher::Rpc_do_dispatch>();
if (_wait_for_irq() == IRQ_TRIGGERED) {
_irq_dispatcher_cap.call<Irq_dispatcher::Rpc_do_dispatch>();
}
}
}

View File

@ -18,8 +18,8 @@
using namespace Genode;
void Timer::Time_source::schedule_timeout(Microseconds duration,
Timeout_handler &handler)
void Timer::Time_source::set_timeout(Microseconds duration,
Timeout_handler &handler)
{
Mutex::Guard mutex_guard(_mutex);
Threaded_time_source::handler(handler);
@ -27,7 +27,8 @@ void Timer::Time_source::schedule_timeout(Microseconds duration,
}
void Timer::Time_source::_wait_for_irq()
Timer::Time_source::Result_of_wait_for_irq
Timer::Time_source::_wait_for_irq()
{
enum { SLEEP_GRANULARITY_US = 1000 };
uint64_t last_time_us = curr_time().trunc_to_plain_us().value;
@ -49,4 +50,5 @@ void Timer::Time_source::_wait_for_irq()
break;
}
_mutex.release();
return IRQ_TRIGGERED;
}

View File

@ -42,7 +42,7 @@ class Timer::Time_source : public Threaded_time_source
** Threaded_time_source **
**************************/
void _wait_for_irq() override;
Result_of_wait_for_irq _wait_for_irq() override;
public:
@ -56,7 +56,7 @@ class Timer::Time_source : public Threaded_time_source
Duration curr_time() override;
Microseconds max_timeout() const override;
void schedule_timeout(Microseconds duration, Timeout_handler &handler) override;
void set_timeout(Microseconds duration, Genode::Timeout_handler &handler) override;
};
#endif /* _TIME_SOURCE_H_ */

View File

@ -49,8 +49,8 @@ uint16_t Timer::Time_source::_read_counter(bool *wrapped)
}
void Timer::Time_source::schedule_timeout(Microseconds duration,
Timeout_handler &handler)
void Timer::Time_source::set_timeout(Microseconds duration,
Timeout_handler &handler)
{
_handler = &handler;
uint64_t duration_us = duration.value;

View File

@ -95,7 +95,7 @@ class Timer::Time_source : public Genode::Signalled_time_source
*************************/
Duration curr_time() override;
void schedule_timeout(Microseconds duration, Timeout_handler &handler) override;
void set_timeout(Microseconds duration, Genode::Timeout_handler &handler) override;
Microseconds max_timeout() const override {
return Microseconds(PIT_MAX_USEC); }
};