From b6efa7f6f98fab1ab306ca08196c48e93433cec8 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 8 Aug 2017 15:18:14 +0200 Subject: [PATCH] timer connection: fast initial calibration The calibration of the interpolation parameters was previously only done periodically every 500 ms. Together with the fact that the parameters had to be stable for at least 3 calibration steps to enable interpolation, it took at least 1.5 seconds after establishing a connection to get microseconds-precise time values. This is a problem for some drivers that directly start to poll time. Thus, the timer connection now does a calibration burst as soon as it switches to the modern mode (the mode with microseconds precision). During this phase it does several (currently 9) calibration steps without a delay inbetween. It is assumed that this is fast enough to not get interrupted by scheduling. Thus, despite being small, the measured values should be very stable which is why the burst should in most cases be sufficient to get the interpolation initialized. Ref #2400 --- repos/os/include/timer_session/connection.h | 1 + repos/os/src/lib/timeout/timer_connection.cc | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/repos/os/include/timer_session/connection.h b/repos/os/include/timer_session/connection.h index 7a6535029e..a0a6fb1f3b 100644 --- a/repos/os/include/timer_session/connection.h +++ b/repos/os/include/timer_session/connection.h @@ -192,6 +192,7 @@ class Timer::Connection : public Genode::Connection, enum { MAX_INTERPOLATION_QUALITY = 3 }; enum { MAX_REMOTE_TIME_LATENCY_US = 500 }; enum { MAX_REMOTE_TIME_TRIALS = 5 }; + enum { NR_OF_INITIAL_CALIBRATIONS = 3 * MAX_INTERPOLATION_QUALITY }; enum { MIN_FACTOR_LOG2 = 8 }; Genode::Io_signal_handler _signal_handler; diff --git a/repos/os/src/lib/timeout/timer_connection.cc b/repos/os/src/lib/timeout/timer_connection.cc index 6cdb03b014..3d2395fddb 100644 --- a/repos/os/src/lib/timeout/timer_connection.cc +++ b/repos/os/src/lib/timeout/timer_connection.cc @@ -119,6 +119,11 @@ void Timer::Connection::_enable_modern_mode() _mode = MODERN; _sigh(_signal_handler); _scheduler._enable(); + + /* do initial calibration burst to make interpolation available earlier */ + for (unsigned i = 0; i < NR_OF_INITIAL_CALIBRATIONS; i++) { + _update_real_time(); + } }