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;
}
uint8_t *rndbuf;
for (*retp = 0, rndbuf = buf; *retp < buflen; (*retp)++) {
- *rndbuf++ = NOW() & 0xff;
+ *rndbuf++ = minios_clock_monotonic() & 0xff;
}
return 0;
-/* 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;
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);
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);
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);
}
* 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 )
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_ */