From e7d590568c160a46b5fcd768b9c8709bcf4be17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 31 Mar 2025 13:25:03 +0200 Subject: [PATCH] kernel: timeout: Reduce number of sys_clock_elapsed calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sys_clock_elapsed requires access to system clock register interface which is often slow. When new relative timeout is added sys_clock_elapsed() is called once to calculate delta ticks and then if that triggers setting new timeout sys_clock_elapsed() is called again. This call is redundant since everything happens under spin lock so it is better to reuse value returned by the first call. Signed-off-by: Krzysztof Chruściński --- kernel/timeout.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/kernel/timeout.c b/kernel/timeout.c index e94d8960fa6..e9231fa3ab8 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -84,10 +84,9 @@ static int32_t elapsed(void) return announce_remaining == 0 ? sys_clock_elapsed() : 0U; } -static int32_t next_timeout(void) +static int32_t next_timeout(int32_t ticks_elapsed) { struct _timeout *to = first(); - int32_t ticks_elapsed = elapsed(); int32_t ret; if ((to == NULL) || @@ -116,9 +115,13 @@ void z_add_timeout(struct _timeout *to, _timeout_func_t fn, K_SPINLOCK(&timeout_lock) { struct _timeout *t; + int32_t ticks_elapsed; + bool has_elapsed = false; if (Z_IS_TIMEOUT_RELATIVE(timeout)) { - to->dticks = timeout.ticks + 1 + elapsed(); + ticks_elapsed = elapsed(); + has_elapsed = true; + to->dticks = timeout.ticks + 1 + ticks_elapsed; } else { k_ticks_t ticks = Z_TICK_ABS(timeout.ticks) - curr_tick; @@ -139,7 +142,13 @@ void z_add_timeout(struct _timeout *to, _timeout_func_t fn, } if (to == first() && announce_remaining == 0) { - sys_clock_set_timeout(next_timeout(), false); + if (!has_elapsed) { + /* In case of absolute timeout that is first to expire + * elapsed need to be read from the system clock. + */ + ticks_elapsed = elapsed(); + } + sys_clock_set_timeout(next_timeout(ticks_elapsed), false); } } } @@ -155,7 +164,7 @@ int z_abort_timeout(struct _timeout *to) remove_timeout(to); ret = 0; if (is_first) { - sys_clock_set_timeout(next_timeout(), false); + sys_clock_set_timeout(next_timeout(elapsed()), false); } } } @@ -210,7 +219,7 @@ int32_t z_get_next_timeout_expiry(void) int32_t ret = (int32_t) K_TICKS_FOREVER; K_SPINLOCK(&timeout_lock) { - ret = next_timeout(); + ret = next_timeout(elapsed()); } return ret; } @@ -257,7 +266,7 @@ void sys_clock_announce(int32_t ticks) curr_tick += announce_remaining; announce_remaining = 0; - sys_clock_set_timeout(next_timeout(), false); + sys_clock_set_timeout(next_timeout(0), false); k_spin_unlock(&timeout_lock, key);