From 59b21a29aa92f3d35692ccde0d194ae53cde3dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Mon, 24 May 2021 11:24:13 +0200 Subject: [PATCH] kernel: timeout: Fix adding of an absolute timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct the way the relative ticks value is calculated for an absolute timeout. Previously, elapsed() was called twice and the returned value was first subtracted from and then added to the ticks value. It could happen that the HW counter value read by elapsed() changed between the two calls to this function. This caused the test_timeout_abs test case from the timer_api test suite to occasionally fail, e.g. on certain nRF platforms. Signed-off-by: Andrzej Głąbek --- kernel/timeout.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/timeout.c b/kernel/timeout.c index 877c2ae7187..09c5a117f35 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -90,20 +90,21 @@ void z_add_timeout(struct _timeout *to, _timeout_func_t fn, __ASSERT_NO_MSG(arch_mem_coherent(to)); #endif - k_ticks_t ticks = timeout.ticks + 1; - - if (IS_ENABLED(CONFIG_TIMEOUT_64BIT) && Z_TICK_ABS(ticks) >= 0) { - ticks = Z_TICK_ABS(timeout.ticks) - (curr_tick + elapsed()); - } - __ASSERT(!sys_dnode_is_linked(&to->node), ""); to->fn = fn; - ticks = MAX(1, ticks); LOCKED(&timeout_lock) { struct _timeout *t; - to->dticks = ticks + elapsed(); + if (IS_ENABLED(CONFIG_TIMEOUT_64BIT) && + Z_TICK_ABS(timeout.ticks) >= 0) { + k_ticks_t ticks = Z_TICK_ABS(timeout.ticks) - curr_tick; + + to->dticks = MAX(1, ticks); + } else { + to->dticks = timeout.ticks + 1 + elapsed(); + } + for (t = first(); t != NULL; t = next(t)) { if (t->dticks > to->dticks) { t->dticks -= to->dticks;