From 8cc24e048e95c56007e8aa5cd2f5a15b9b43a6db Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 11 Apr 2025 14:56:14 +0200 Subject: [PATCH] fixup "hw: sanitize scheduler, cpu, and timer interplay" (timer) --- repos/base-hw/src/core/kernel/scheduler.cc | 4 +-- repos/base-hw/src/core/kernel/thread.cc | 2 +- repos/base-hw/src/core/kernel/timer.cc | 31 ++++++++++++---------- repos/base-hw/src/core/kernel/timer.h | 9 +++---- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/repos/base-hw/src/core/kernel/scheduler.cc b/repos/base-hw/src/core/kernel/scheduler.cc index e9fd8d1d2a..ce80b20c83 100644 --- a/repos/base-hw/src/core/kernel/scheduler.cc +++ b/repos/base-hw/src/core/kernel/scheduler.cc @@ -186,10 +186,8 @@ void Scheduler::update() if (!_schedule_slack()) _set_current(_idle, _slack_quota); - _timer.set_timeout(&_timeout, + _timer.set_timeout(_timeout, Genode::min(_current_quantum, _super_period_left)); - _timer.schedule_timeout(); - } diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index fafe75e07f..e7f80f9b8f 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -507,7 +507,7 @@ void Thread::_call_timeout() { Timer & t = _cpu().timer(); _timeout_sigid = (Kernel::capid_t)user_arg_2(); - t.set_timeout(this, t.us_to_ticks(user_arg_1())); + t.set_timeout(*this, t.us_to_ticks(user_arg_1())); } diff --git a/repos/base-hw/src/core/kernel/timer.cc b/repos/base-hw/src/core/kernel/timer.cc index 39ecf8df70..f6255db6e4 100644 --- a/repos/base-hw/src/core/kernel/timer.cc +++ b/repos/base-hw/src/core/kernel/timer.cc @@ -36,19 +36,19 @@ time_t Timer::timeout_max_us() const } -void Timer::set_timeout(Timeout * const timeout, time_t const duration) +void Timer::set_timeout(Timeout &timeout, time_t const duration) { /* * Remove timeout if it is already in use. Timeouts may get overridden as * result of an update. */ - if (timeout->_listed) - _timeout_list.remove(timeout); + if (timeout._listed) + _timeout_list.remove(&timeout); else - timeout->_listed = true; + timeout._listed = true; /* set timeout parameters */ - timeout->_end = time() + duration; + timeout._end = time() + duration; /* * Insert timeout. Timeouts are ordered ascending according to their end @@ -56,26 +56,26 @@ void Timer::set_timeout(Timeout * const timeout, time_t const duration) */ Timeout * t1 = 0; for (Timeout * t2 = _timeout_list.first(); - t2 && t2->_end < timeout->_end; + t2 && t2->_end < timeout._end; t1 = t2, t2 = t2->next()) { } - _timeout_list.insert(timeout, t1); + _timeout_list.insert(&timeout, t1); + + if (_timeout_list.first() == &timeout) + _schedule_timeout(); } -time_t Timer::schedule_timeout() +void Timer::_schedule_timeout() { /* get the timeout with the nearest end time */ Timeout * timeout = _timeout_list.first(); - assert(timeout); + time_t end = timeout ? timeout->_end : _time + _max_value(); /* install timeout at timer hardware */ - time_t duration = _duration(); - _time += duration; - _last_timeout_duration = (timeout->_end > _time) ? timeout->_end - _time : 1; + _time += _duration(); + _last_timeout_duration = (end > _time) ? end - _time : 1; _start_one_shot(_last_timeout_duration); - - return duration; } @@ -97,6 +97,9 @@ void Timer::_process_timeouts() timeout->_listed = false; timeout->timeout_triggered(); } + + if (_timeout_list.first()) + _schedule_timeout(); } diff --git a/repos/base-hw/src/core/kernel/timer.h b/repos/base-hw/src/core/kernel/timer.h index ac92d2bfca..09c2dc6508 100644 --- a/repos/base-hw/src/core/kernel/timer.h +++ b/repos/base-hw/src/core/kernel/timer.h @@ -90,16 +90,13 @@ class Kernel::Timer void _process_timeouts(); + void _schedule_timeout(); + public: Timer(Cpu & cpu); - /** - * Return duration from last call of this function - */ - time_t schedule_timeout(); - - void set_timeout(Timeout * const timeout, time_t const duration); + void set_timeout(Timeout &timeout, time_t const duration); time_t us_to_ticks(time_t const us) const;