Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions arch/arm64/src/common/arm64_arch_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ static int arm64_tick_start(struct oneshot_lowerhalf_s *lower,
{
struct arm64_oneshot_lowerhalf_s *priv =
(struct arm64_oneshot_lowerhalf_s *)lower;
uint64_t next_cycle;

DEBUGASSERT(priv != NULL && callback != NULL);

Expand All @@ -252,10 +253,11 @@ static int arm64_tick_start(struct oneshot_lowerhalf_s *lower,
priv->callback = callback;
priv->arg = arg;

/* Set the timeout */
next_cycle =
arm64_arch_timer_count() / priv->cycle_per_tick * priv->cycle_per_tick +
ticks * priv->cycle_per_tick;

arm64_arch_timer_set_compare(arm64_arch_timer_count() +
priv->cycle_per_tick * ticks);
arm64_arch_timer_set_compare(next_cycle);
arm64_arch_timer_set_irq_mask(false);

return OK;
Expand Down Expand Up @@ -418,4 +420,4 @@ void arm64_arch_timer_secondary_init()
arm64_arch_timer_enable(true);
#endif
}
#endif
#endif
32 changes: 20 additions & 12 deletions drivers/timers/arch_alarm.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,26 +116,34 @@ static void udelay_coarse(useconds_t microseconds)
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
FAR void *arg)
{
clock_t now = 0;
clock_t now;
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);

#ifdef CONFIG_SCHED_TICKLESS
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);
nxsched_alarm_tick_expiration(now);
#else
clock_t delta;
/* Start the next tick first, in order to minimize latency. Ideally
* the ONESHOT_TICK_START would also return the current tick so that
* the retriving the current tick and starting the new one could be done
* atomically w. respect to a HW timer
*/

do
{
clock_t next;
ONESHOT_TICK_START(g_oneshot_lower, oneshot_callback, NULL, 1);

/* It is always an error if this progresses more than 1 tick at a time.
* That would break any timer based on wdog; such timers might timeout
* early. Add a DEBUGASSERT here to catch those errors. It is not added
* here by default, since it would break debugging. These errors
* would occur due to HW timers possibly running while CPU is being halted.
*/

/* DEBUGASSERT(now - g_current_tick <= 1); */

while (now - g_current_tick > 0)
{
g_current_tick++;
nxsched_process_timer();
next = ++g_current_tick;
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);
delta = next - now;
}
while ((sclock_t)delta <= 0);

ONESHOT_TICK_START(g_oneshot_lower, oneshot_callback, NULL, delta);
#endif
}

Expand Down
5 changes: 3 additions & 2 deletions sched/semaphore/sem_tickwait.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 (; ; )
Expand Down