]> xenbits.xensource.com Git - rumpuser-xen.git/commitdiff
Implement wall clock time (rumprun-xen issue #13)
authorMartin Lucina <martin@lucina.net>
Sun, 28 Dec 2014 17:12:40 +0000 (18:12 +0100)
committerMartin Lucina <martin@lucina.net>
Sun, 28 Dec 2014 17:12:40 +0000 (18:12 +0100)
This change adds minios_clock_wall() as a global symbol to return wall
clock time from Xen. I did not reinstate the minios "gettime()" which is
available upstream as that relies on a definitition of struct timeval.

minios_monotonic_clock() is renamed to minios_clock_monotonic() for
consistency.

rumpuser_clock_gettime() is updated to support RUMPUSER_CLOCK_REWALL,
returning wall clock time.

All rumphyper calls to the minios NOW() macro are replaced with calls to
the properly namespaces minios_clock_monotonic().

Signed-off-by: Martin Lucina <martin@lucina.net>
rumphyper_base.c
rumphyper_synch.c
xen/arch/x86/time.c
xen/include/mini-os/time.h

index b911881e360eec10ffdff28a14d4810a9dd92855..bfd68eff5eb70ce8951fe8ecf2afa9658188a7d1 100644 (file)
@@ -149,10 +149,24 @@ rumpuser_getparam(const char *name, void *buf, size_t buflen)
 int
 rumpuser_clock_gettime(int which, int64_t *sec, long *nsec)
 {
-       s_time_t time = NOW();
+       int64_t outsec;
+       long outnsec;
+       uint64_t time;
 
-       *sec  = time / (1000*1000*1000ULL);
-       *nsec = time % (1000*1000*1000ULL);
+       switch (which) {
+       case RUMPUSER_CLOCK_RELWALL:
+               minios_clock_wall(&outsec, &outnsec);
+
+               *sec = outsec;
+               *nsec = outnsec;
+               break;
+       case RUMPUSER_CLOCK_ABSMONO:
+               time = minios_clock_monotonic();
+
+               *sec  = time / (1000*1000*1000ULL);
+               *nsec = time % (1000*1000*1000ULL);
+               break;
+       }
 
        return 0;
 }
@@ -233,7 +247,7 @@ rumpuser_getrandom(void *buf, size_t buflen, int flags, size_t *retp)
        uint8_t *rndbuf;
 
        for (*retp = 0, rndbuf = buf; *retp < buflen; (*retp)++) {
-               *rndbuf++ = NOW() & 0xff;
+               *rndbuf++ = minios_clock_monotonic() & 0xff;
        }
 
        return 0;
index ae10a233529ace26b1adec80600c4a496bc28ea0..a8b87d5ed30a0184b75efa04289e056ec5166874 100644 (file)
@@ -61,7 +61,7 @@ wait(struct waithead *wh, uint64_t nsec)
        w.onlist = 1;
        minios_block(w.who);
        if (nsec)
-               w.who->wakeup_time = NOW() + nsec;
+               w.who->wakeup_time = minios_clock_monotonic() + nsec;
        minios_schedule();
 
        /* woken up by timeout? */
index c86f45a31f5adc2de7580fea6869dd59dfbca247..503ea4a56f71cffa250b96e8da9225f60c02e7dd 100644 (file)
@@ -146,11 +146,12 @@ static void get_time_values_from_xen(void)
 
 
 
-/* monotonic_clock(): returns # of nanoseconds passed since time_init()
+/* minios_clock_monotonic():
+ *              returns # of nanoseconds passed since time_init()
  *             Note: This function is required to return accurate
  *             time even in the absence of multiple timer ticks.
  */
-uint64_t minios_monotonic_clock(void)
+uint64_t minios_clock_monotonic(void)
 {
        uint64_t time;
        uint32_t local_time_version;
@@ -159,7 +160,7 @@ uint64_t minios_monotonic_clock(void)
                local_time_version = shadow.version;
                rmb();
                time = shadow.system_timestamp + get_nsec_offset();
-        if (!time_values_up_to_date())
+                if (!time_values_up_to_date())
                        get_time_values_from_xen();
                rmb();
        } while (local_time_version != shadow.version);
@@ -181,11 +182,21 @@ static void update_wallclock(void)
        while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version));
 }
 
+/* minios_clock_wall():
+ *                    returns seconds and nanoseconds passed since the epoch.
+ */
+void minios_clock_wall(uint32_t *sec, uint64_t *nsec)
+{
+        uint64_t now = minios_clock_monotonic();
+
+        *sec = shadow_ts.tv_sec + NSEC_TO_SEC(now);
+        *nsec = shadow_ts.tv_nsec + (now / 1000000000UL);
+}
 
 void block_domain(s_time_t until)
 {
     ASSERT(irqs_disabled());
-    if(minios_monotonic_clock() < until)
+    if(minios_clock_monotonic() < until)
     {
         HYPERVISOR_set_timer_op(until);
         HYPERVISOR_sched_op(SCHEDOP_block, 0);
@@ -209,6 +220,10 @@ static evtchn_port_t port;
 void init_time(void)
 {
     minios_printk("Initialising timer interface\n");
+    /* ensure time values are up to date after exit from this function */
+    get_time_values_from_xen();
+    update_wallclock();
+    /* start timer handler */
     port = minios_bind_virq(VIRQ_TIMER, &timer_handler, NULL);
     minios_unmask_evtchn(port);
 }
index 8bb0f8ef649552d097327d47a8a6f74229875b31..b5df99ad52035820a1bb2609c2c947110e67bf2e 100644 (file)
@@ -30,7 +30,7 @@
  * of real time into system time 
  */
 typedef int64_t s_time_t;
-#define NOW()                   ((s_time_t)minios_monotonic_clock())
+#define NOW()                   ((s_time_t)minios_clock_monotonic())
 #define SECONDS(_s)             (((s_time_t)(_s))  * 1000000000UL )
 #define TENTHS(_ts)             (((s_time_t)(_ts)) * 100000000UL )
 #define HUNDREDTHS(_hs)         (((s_time_t)(_hs)) * 10000000UL )
@@ -50,7 +50,8 @@ void     init_time(void);
 void     fini_time(void);
 s_time_t get_s_time(void);
 s_time_t get_v_time(void);
-uint64_t minios_monotonic_clock(void);
+uint64_t minios_clock_monotonic(void);
+void     minios_clock_wall(uint32_t *sec, uint64_t *nsec);
 void     block_domain(s_time_t until);
 
 #endif /* _MINIOS_TIME_H_ */