mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-19 16:41:26 +00:00
timer: read PIT timer solely after interrupt
Stop gap solution until #2579 gets resolved.
This commit is contained in:
parent
2ba5f8f4f3
commit
80778b267d
repos/os/src/drivers/timer
@ -30,11 +30,16 @@ class Genode::Signalled_time_source : public Time_source
|
||||
|
||||
Signal_handler _signal_handler;
|
||||
Timeout_handler *_handler = nullptr;
|
||||
bool _irq = false;
|
||||
|
||||
void _handle_timeout()
|
||||
{
|
||||
if (_handler) {
|
||||
_handler->handle_timeout(curr_time()); }
|
||||
_irq = true;
|
||||
Duration time(curr_time());
|
||||
_irq = false;
|
||||
_handler->handle_timeout(time);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -53,19 +53,27 @@ void Timer::Time_source::schedule_timeout(Microseconds duration,
|
||||
Timeout_handler &handler)
|
||||
{
|
||||
_handler = &handler;
|
||||
_timer_irq.ack_irq();
|
||||
unsigned long duration_us = duration.value;
|
||||
|
||||
/* limit timer-interrupt rate */
|
||||
enum { MAX_TIMER_IRQS_PER_SECOND = 4*1000 };
|
||||
if (duration_us < 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND)
|
||||
duration_us = 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND;
|
||||
|
||||
if (duration_us > max_timeout().value)
|
||||
/* timeout '0' is trigger to cancel the current pending, if required */
|
||||
if (!duration.value) {
|
||||
duration_us = max_timeout().value;
|
||||
Signal_transmitter(_signal_handler).submit();
|
||||
} else {
|
||||
/* limit timer-interrupt rate */
|
||||
enum { MAX_TIMER_IRQS_PER_SECOND = 4*1000 };
|
||||
if (duration_us < 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND)
|
||||
duration_us = 1000 * 1000 / MAX_TIMER_IRQS_PER_SECOND;
|
||||
|
||||
if (duration_us > max_timeout().value)
|
||||
duration_us = max_timeout().value;
|
||||
}
|
||||
|
||||
_counter_init_value = (PIT_TICKS_PER_MSEC * duration_us) / 1000;
|
||||
_set_counter(_counter_init_value);
|
||||
|
||||
if (duration.value)
|
||||
_timer_irq.ack_irq();
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +101,16 @@ uint32_t Timer::Time_source::_ticks_since_update_one_wrap(uint16_t curr_counter)
|
||||
|
||||
|
||||
Duration Timer::Time_source::curr_time()
|
||||
{
|
||||
/* read out and update curr time solely if running in context of irq */
|
||||
if (_irq)
|
||||
_curr_time();
|
||||
|
||||
return Duration(Microseconds(_curr_time_us));
|
||||
}
|
||||
|
||||
|
||||
Duration Timer::Time_source::_curr_time()
|
||||
{
|
||||
/* read PIT counter and wrapped status */
|
||||
uint32_t ticks;
|
||||
|
@ -82,6 +82,8 @@ class Timer::Time_source : public Genode::Signalled_time_source
|
||||
|
||||
Genode::uint32_t _ticks_since_update_no_wrap(Genode::uint16_t curr_counter);
|
||||
|
||||
Duration _curr_time();
|
||||
|
||||
public:
|
||||
|
||||
Time_source(Genode::Env &env);
|
||||
|
Loading…
x
Reference in New Issue
Block a user