From 8fd914c6ab4b234104a80e6d079bd59dc442aa82 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 12 Sep 2017 14:26:45 +0200 Subject: [PATCH] timeout: fix outdated time in alarm scheduler If we add an absolute timeout to the back-end alarm-scheduler we must first call 'handle' at the scheduler to update its internal time value. Otherwise, it might happen that we add a timeout who's deadline is so big that it normally belongs to the next time-counter period but the scheduler thinks that it belongs to the current period as its time is older than the one used to calculate the deadline. Ref #2490 --- repos/os/src/lib/timeout/timeout.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/repos/os/src/lib/timeout/timeout.cc b/repos/os/src/lib/timeout/timeout.cc index 4846f7a0c..27739adee 100644 --- a/repos/os/src/lib/timeout/timeout.cc +++ b/repos/os/src/lib/timeout/timeout.cc @@ -102,9 +102,13 @@ void Alarm_timeout_scheduler::_enable() void Alarm_timeout_scheduler::_schedule_one_shot(Timeout &timeout, Microseconds duration) { - _alarm_scheduler.schedule_absolute( - &timeout._alarm, - _time_source.curr_time().trunc_to_plain_us().value + duration.value); + unsigned long const curr_time_us = + _time_source.curr_time().trunc_to_plain_us().value; + + /* ensure that the schedulers time is up-to-date before adding a timeout */ + _alarm_scheduler.handle(curr_time_us); + _alarm_scheduler.schedule_absolute(&timeout._alarm, + curr_time_us + duration.value); if (_alarm_scheduler.head_timeout(&timeout._alarm)) { _time_source.schedule_timeout(Microseconds(0), *this); } @@ -114,8 +118,10 @@ void Alarm_timeout_scheduler::_schedule_one_shot(Timeout &timeout, void Alarm_timeout_scheduler::_schedule_periodic(Timeout &timeout, Microseconds duration) { + /* ensure that the schedulers time is up-to-date before adding a timeout */ _alarm_scheduler.handle(_time_source.curr_time().trunc_to_plain_us().value); _alarm_scheduler.schedule(&timeout._alarm, duration.value); + if (_alarm_scheduler.head_timeout(&timeout._alarm)) { _time_source.schedule_timeout(Microseconds(0), *this); } }