From 518c3746fd032147bef5cbb5d6461c8628faa30a Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Wed, 10 Jan 2018 09:10:29 +0000 Subject: [PATCH] Clean up that CLOCK mess Generalized getting a time stamp related to the simulation. Make it really portable. Signed-off-by: Michel Pollet --- simavr/sim/sim_avr.c | 35 +++++++++++++++++++++++------------ simavr/sim/sim_avr.h | 6 +++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c index 6106df6..1878b41 100644 --- a/simavr/sim/sim_avr.c +++ b/simavr/sim/sim_avr.c @@ -71,6 +71,26 @@ avr_global_logger_get(void) return _avr_global_logger; } +uint64_t +avr_get_time_stamp( + avr_t * avr ) +{ + uint64_t stamp; +#ifndef CLOCK_MONOTONIC_RAW + /* CLOCK_MONOTONIC_RAW isn't portable, here is the POSIX alternative. + * Only downside is that it will drift if the system clock changes */ + struct timeval tv; + gettimeofday(&tv, NULL); + stamp = (((uint64_t)tv.tv_sec) * 1E9) + (tv.tv_usec * 1000); +#else + struct timespec tp; + clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + stamp = (tp.tv_sec * 1E9) + tp.tv_nsec; +#endif + if (!avr->time_base) + avr->time_base = stamp; + return stamp - avr->time_base; +} int avr_init( @@ -149,10 +169,6 @@ avr_reset( avr->sreg[i] = 0; avr_interrupt_reset(avr); avr_cycle_timer_reset(avr); - /* Take simulation start time */ - struct timespec tp; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp); - avr->sim_start_time_ns = tp.tv_sec*1E9+tp.tv_nsec; if (avr->reset) avr->reset(avr); avr_io_t * port = avr->io_port; @@ -327,17 +343,12 @@ avr_callback_sleep_raw( avr_t *avr, avr_cycle_count_t how_long) { - struct timespec tp; - /* figure out how long we should wait to match the sleep deadline */ uint64_t deadline_ns = avr_cycles_to_nsec(avr, avr->cycle + how_long); - clock_gettime(CLOCK_MONOTONIC_RAW, &tp); - uint64_t runtime_ns = (tp.tv_sec*1E9+tp.tv_nsec) - avr->sim_start_time_ns; - if (runtime_ns >= deadline_ns) { + uint64_t runtime_ns = avr_get_time_stamp(avr); + if (runtime_ns >= deadline_ns) return; - } - - uint64_t sleep_us = (deadline_ns - runtime_ns)/1000; + uint64_t sleep_us = (deadline_ns - runtime_ns) / 1000; usleep(sleep_us); return; } diff --git a/simavr/sim/sim_avr.h b/simavr/sim/sim_avr.h index 92459dc..3553976 100644 --- a/simavr/sim/sim_avr.h +++ b/simavr/sim/sim_avr.h @@ -201,7 +201,7 @@ typedef struct avr_t { * is passed on to the operating system. */ uint32_t sleep_usec; - uint64_t sim_start_time_ns; + uint64_t time_base; // for avr_get_time_stamp() // called at init time void (*init)(struct avr_t * avr); @@ -476,6 +476,10 @@ uint32_t avr_pending_sleep_usec( avr_t * avr, avr_cycle_count_t howLong); +/* Return the number of 'real time' spent since sim started, in uS */ +uint64_t +avr_get_time_stamp( + avr_t * avr ); #ifdef __cplusplus }; -- 2.39.5