From e9cdcc235f140fdb185b92ffe7bd59bcc2fcfcc5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 29 Jul 2019 13:48:55 +0200 Subject: [PATCH] kernel: timeout: Fix macro usage in next_timeout function The `next_timeout()` function used to call the `elapsed()` function directly in the `MAX` macro call. This caused the `elapsed()` function to be executed twice, with possible different results, if the system clock incremented its value in a meantime. As a result, the whole `MAX(0, to->dticks - elapsed()` expresion could return an incorrect value of -1, which represents the K_FOREVER timeout. This led to a stall in devices running tickless kernel (as observed on nRF52840). Signed-off-by: Robert Lubos --- kernel/timeout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/timeout.c b/kernel/timeout.c index 52bb2ef9903..99f3d24c85c 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -69,7 +69,8 @@ static s32_t elapsed(void) static s32_t next_timeout(void) { struct _timeout *to = first(); - s32_t ret = to == NULL ? MAX_WAIT : MAX(0, to->dticks - elapsed()); + s32_t ticks_elapsed = elapsed(); + s32_t ret = to == NULL ? MAX_WAIT : MAX(0, to->dticks - ticks_elapsed); #ifdef CONFIG_TIMESLICING if (_current_cpu->slice_ticks && _current_cpu->slice_ticks < ret) {