From 8d60bc11b5da4737b08cad283071bc04e24dae94 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Mon, 2 Dec 2019 15:38:27 +0100 Subject: [PATCH] vbox: periodic timer based on absolute timestamps Before timestamps where calculated as durations since current wakeup which introduces a systematical drift. --- repos/ports/src/virtualbox5/spec/nova/sup.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 71b968e16..37ad11515 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -711,21 +711,20 @@ void genode_update_tsc(void (*update_func)(void), Genode::uint64_t update_us) using namespace Genode; using namespace Nova; - enum { TSC_FACTOR = 1000ULL }; + Trace::Timestamp const ticks_per_us = genode_cpu_hz() / (1000*1000); + Trace::Timestamp const ticks_per_update = ticks_per_us * update_us; + Trace::Timestamp const ticks_min_sleep = ticks_per_us * 100; + Trace::Timestamp wakeup_absolute = Trace::timestamp(); Genode::addr_t sem = Thread::myself()->native_thread().exc_pt_sel + Nova::SM_SEL_EC; - unsigned long tsc_khz = (genode_cpu_hz() / 1000) / TSC_FACTOR; - - Trace::Timestamp us_64 = update_us; - for (;;) { update_func(); - Trace::Timestamp now = Trace::timestamp(); + wakeup_absolute = max(wakeup_absolute + ticks_per_update, + Trace::timestamp() + ticks_min_sleep); /* block until timeout fires or it gets canceled */ - unsigned long long tsc_absolute = now + us_64 * tsc_khz; - Genode::uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, tsc_absolute); + Genode::uint8_t res = sm_ctrl(sem, SEMAPHORE_DOWN, wakeup_absolute); if (res != Nova::NOVA_OK && res != Nova::NOVA_TIMEOUT) nova_die(); }