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 <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2019-07-29 13:48:55 +02:00 committed by Carles Cufí
commit e9cdcc235f

View file

@ -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) {