From 42bc72e2663554b5e64d541d329c24628e355663 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Fri, 27 Sep 2024 09:43:47 +0300 Subject: [PATCH] sched/semaphore/sem_tickwait.c: Fix nxsem_tickwait_uninterruptible end condition nxsem_tickwait correctly sleeps more than 1 tick. But nxsem_tickwait_uninterruptible may wake up to a signal (with -EINTR), in which case the tick + 1 must also be taken into account. Otherwise the nxsem_tickwait_uninterruptible may wake up 1 tick too early. This patch has the side effect that if such a wakeup by signal occurs at the last waiting tick, the nxsem_tickwait_uninterruptible may end up sleeping one tick too long due to nxsem_tickwait won't ever timeout at the next tick. This is however (more) correct behaviour than waking up too early. Also fix the nxsem_tickwait to return with -ETIMEDOUT if called with delay 0. This is similar to e.g. posix sem_timedwait. Signed-off-by: Jukka Laitinen --- arch/arm64/src/common/arm64_arch_timer.c | 5 +++++ sched/semaphore/sem_tickwait.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm64/src/common/arm64_arch_timer.c b/arch/arm64/src/common/arm64_arch_timer.c index f2eba064b7a83..5509d2b31bdc0 100644 --- a/arch/arm64/src/common/arm64_arch_timer.c +++ b/arch/arm64/src/common/arm64_arch_timer.c @@ -259,6 +259,11 @@ static int arm64_tick_start(struct oneshot_lowerhalf_s *lower, if (count_now - priv->next_cycle >= tick_counts) { + /* Align the next_cycle to be evenly divisible by cycle_per_tick. + * This will ensure that any call to arm64_tick_current always + * returns the currently ongoing tick. + */ + priv->next_cycle = (count_now / priv->cycle_per_tick) * priv->cycle_per_tick; } diff --git a/sched/semaphore/sem_tickwait.c b/sched/semaphore/sem_tickwait.c index 76d189fd0df92..2fb2b3f93653c 100644 --- a/sched/semaphore/sem_tickwait.c +++ b/sched/semaphore/sem_tickwait.c @@ -100,8 +100,9 @@ int nxsem_tickwait(FAR sem_t *sem, uint32_t delay) if (delay == 0) { - /* Return the errno from nxsem_trywait() */ + /* Timed out already before waiting */ + ret = -ETIMEDOUT; goto out; } @@ -149,7 +150,7 @@ int nxsem_tickwait(FAR sem_t *sem, uint32_t delay) int nxsem_tickwait_uninterruptible(FAR sem_t *sem, uint32_t delay) { - clock_t end = clock_systime_ticks() + delay; + clock_t end = clock_systime_ticks() + delay + 1; int ret; for (; ; )