From 49481dd3fbed7085fedf10b926c1da1daf5cda28 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 1 Apr 2021 13:21:18 +0200 Subject: [PATCH] timer: restore semantics of periodic timeout 0 The 'Timer::Session::trigger_periodic' RPC function used to accept 0 as a way to de-schedule the periodic processing. Several components such as nitpicker relied on this special case. In "timeout: rework timeout framework", the value of zero was silently clamped to 1, which has the opposite effect: triggering signals at the maximum rate. This results in a visible effect in Sculpt where the leitzentrale-nitpicker instance produces a constant load of 2% CPU time. This patch restores the original timer semantics by - Documenting it in timer_session.h, - Handling the case explicitly in the timer implementation, and - Replacing the silent clamping of the unexpected value 0 passed to the timeout framework by a diagnostic error message. Issue #3884 --- repos/base/include/timer_session/timer_session.h | 3 ++- repos/base/src/lib/timeout/timeout.cc | 3 ++- repos/base/src/timer/include/session_component.h | 13 +++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/repos/base/include/timer_session/timer_session.h b/repos/base/include/timer_session/timer_session.h index 1df9a7db3b..f552a39ac9 100644 --- a/repos/base/include/timer_session/timer_session.h +++ b/repos/base/include/timer_session/timer_session.h @@ -49,7 +49,8 @@ struct Timer::Session : Genode::Session * Program periodic timeout (in microseconds) * * The first period will be triggered after 'us' at the latest, - * but it might be triggered earlier as well. + * but it might be triggered earlier as well. The 'us' value 0 + * disables periodic timeouts. */ virtual void trigger_periodic(uint64_t us) = 0; diff --git a/repos/base/src/lib/timeout/timeout.cc b/repos/base/src/lib/timeout/timeout.cc index 2edda0cbf5..84d35e44bb 100644 --- a/repos/base/src/lib/timeout/timeout.cc +++ b/repos/base/src/lib/timeout/timeout.cc @@ -276,7 +276,8 @@ void Timeout_scheduler::_schedule_periodic_timeout(Timeout &timeout, /* prevent using a period of 0 */ if (period.value == 0) { - period.value = 1; + error("attempt to schedule a periodic timeout of 0"); + return; } _schedule_timeout(timeout, Microseconds { 0 }, period, handler); } diff --git a/repos/base/src/timer/include/session_component.h b/repos/base/src/timer/include/session_component.h index d9f3058287..dd9c456355 100644 --- a/repos/base/src/timer/include/session_component.h +++ b/repos/base/src/timer/include/session_component.h @@ -65,8 +65,8 @@ class Timer::Session_component : public Genode::Rpc_object, ** Timer::Session ** ********************/ - void trigger_once(uint64_t us) override { - + void trigger_once(uint64_t us) override + { /* * FIXME Workaround for the problem that Alarm scheduler may * categorize big timeouts into the wrong time counter @@ -80,8 +80,13 @@ class Timer::Session_component : public Genode::Rpc_object, _timeout.schedule_one_shot(typed_us, *this); } - void trigger_periodic(uint64_t us) override { - _timeout.schedule_periodic(Microseconds(us), *this); } + void trigger_periodic(uint64_t us) override + { + if (us) + _timeout.schedule_periodic(Microseconds(us), *this); + else + _timeout.discard(); + } void sigh(Signal_context_capability sigh) override {