mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-17 06:38:28 +00:00
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:
committed by
Christian Helmuth
parent
9e5d479d03
commit
7feea78991
@ -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;
|
||||
|
@ -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; };
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
/********************
|
||||
|
@ -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(); }
|
||||
|
||||
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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); }
|
||||
};
|
||||
|
Reference in New Issue
Block a user