Commit 518c3746fd032147bef5cbb5d6461c8628faa30a
authorMichel Pollet <buserror@gmail.com>
Wed, 10 Jan 2018 09:10:29 +0000 (09:10 +0000)
committerMichel Pollet <buserror@gmail.com>
Wed, 10 Jan 2018 09:10:29 +0000 (09:10 +0000)
Generalized getting a time stamp related to the simulation. Make it
really portable.

Signed-off-by: Michel Pollet <buserror@gmail.com>
2 files changed:
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h

index 6106df6041ebf22411a20e4ba3571ed3327dfa38..1878b4190ceceab263c0bcd875a323c7a707c631 100644 (file)
@@ -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;
 }
index 92459dc0f65b4d86d24cd9688230a660e2948261..35539761b040fd1a0a3de88a551c6f71b20cec6c 100644 (file)
@@ -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
 };