Skip to content

Commit

Permalink
kernel: timeout: Fix adding of an absolute timeout
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
anangl authored and nashif committed May 25, 2021
1 parent 851d14a commit 59b21a2
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions kernel/timeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 59b21a2

Please sign in to comment.