diff --git a/arch/sim/src/sim/up_hosttime.c b/arch/sim/src/sim/up_hosttime.c index 54c81a5d61a..387c52d69af 100644 --- a/arch/sim/src/sim/up_hosttime.c +++ b/arch/sim/src/sim/up_hosttime.c @@ -55,10 +55,24 @@ uint64_t host_gettime(bool rtc) { + static uint64_t start; struct timespec tp; + uint64_t current; clock_gettime(rtc ? CLOCK_REALTIME : CLOCK_MONOTONIC, &tp); - return 1000000000ull * tp.tv_sec + tp.tv_nsec; + current = 1000000000ull * tp.tv_sec + tp.tv_nsec; + + if (rtc) + { + return current; + } + + if (start == 0) + { + start = current; + } + + return current - start; } /**************************************************************************** @@ -76,17 +90,9 @@ void host_sleep(uint64_t nsec) void host_sleepuntil(uint64_t nsec) { - static uint64_t base; uint64_t now; now = host_gettime(false); - if (base == 0) - { - base = now; - } - - now -= base; - if (nsec > now + 1000) { usleep((nsec - now) / 1000); diff --git a/arch/sim/src/sim/up_oneshot.c b/arch/sim/src/sim/up_oneshot.c index ec0c6311bed..63a2220197b 100644 --- a/arch/sim/src/sim/up_oneshot.c +++ b/arch/sim/src/sim/up_oneshot.c @@ -100,7 +100,6 @@ static int sim_current(FAR struct oneshot_lowerhalf_s *lower, * Private Data ****************************************************************************/ -static struct timespec g_current; static sq_queue_t g_oneshot_list; /* Lower half operations */ @@ -117,6 +116,27 @@ static const struct oneshot_operations_s g_oneshot_ops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: sim_timer_current + * + * Description: + * Get current time from host. + * + ****************************************************************************/ + +static inline void sim_timer_current(FAR struct timespec *ts) +{ + uint64_t nsec; + time_t sec; + + nsec = host_gettime(false); + sec = nsec / NSEC_PER_SEC; + nsec -= sec * NSEC_PER_SEC; + + ts->tv_sec = sec; + ts->tv_nsec = nsec; +} + /**************************************************************************** * Name: sim_timer_update * @@ -128,16 +148,8 @@ static const struct oneshot_operations_s g_oneshot_ops = static void sim_timer_update(void) { - static const struct timespec tick = - { - .tv_sec = 0, - .tv_nsec = NSEC_PER_TICK, - }; - FAR sq_entry_t *entry; - clock_timespec_add(&g_current, &tick, &g_current); - for (entry = sq_peek(&g_oneshot_list); entry; entry = sq_next(entry)) { sim_process_tick(entry); @@ -169,7 +181,10 @@ static void sim_process_tick(sq_entry_t *entry) if (priv->callback) { - if (clock_timespec_compare(&priv->alarm, &g_current) > 0) + struct timespec current; + + sim_timer_current(¤t); + if (clock_timespec_compare(&priv->alarm, ¤t) > 0) { return; /* Alarm doesn't expire yet */ } @@ -243,10 +258,12 @@ static int sim_start(FAR struct oneshot_lowerhalf_s *lower, { FAR struct sim_oneshot_lowerhalf_s *priv = (FAR struct sim_oneshot_lowerhalf_s *)lower; + struct timespec current; DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL); - clock_timespec_add(&g_current, ts, &priv->alarm); + sim_timer_current(¤t); + clock_timespec_add(¤t, ts, &priv->alarm); priv->callback = callback; priv->arg = arg; @@ -283,10 +300,12 @@ static int sim_cancel(FAR struct oneshot_lowerhalf_s *lower, { FAR struct sim_oneshot_lowerhalf_s *priv = (FAR struct sim_oneshot_lowerhalf_s *)lower; + struct timespec current; DEBUGASSERT(priv != NULL && ts != NULL); - clock_timespec_subtract(&priv->alarm, &g_current, ts); + sim_timer_current(¤t); + clock_timespec_subtract(&priv->alarm, ¤t, ts); priv->callback = NULL; priv->arg = NULL; @@ -323,7 +342,8 @@ static int sim_current(FAR struct oneshot_lowerhalf_s *lower, DEBUGASSERT(priv != NULL && ts != NULL); - *ts = g_current; + sim_timer_current(ts); + return OK; } @@ -437,15 +457,14 @@ void up_timer_initialize(void) void up_timer_update(void) { -#ifdef CONFIG_SIM_WALLTIME_SLEEP + static uint64_t until; /* Wait a bit so that the timing is close to the correct rate. */ - host_sleepuntil(g_current.tv_nsec + - (uint64_t)g_current.tv_sec * NSEC_PER_SEC); -#endif + until += NSEC_PER_TICK; + host_sleepuntil(until); -#ifndef CONFIG_SIM_WALLTIME_SIGNAL +#ifdef CONFIG_SIM_WALLTIME_SLEEP sim_timer_update(); #endif }