timer connection: relax factor shifting

When in modern mode (with local time interpolation), the timer
connection used to maximize the left shifting of its
timestamp-to-microseconds factor. The higher the shift the more precise
is the translation from timestamps to microseconds. If the timestamp
values used for determining the best shift were small - i.e.  the delay
between the calibration steps were small - we may got a pretty big
shift.  If we then used the shift with bigger timestamp values - i.e.
called curr_time seldom or raised calibration delays - the big shift
value became a problem. The framework had to scale down all measured
timestamps and time values temporarily to stay operative until the next
calibration step.

Thus, we now raise the shift only that much that the resulting factor
fullfills a given minimum. This keeps it as low as possible according
to the precision requirement. Currently, this requirement is set to 8
meaning that the shifted factor shall be at least 2^8 = 256.

Ref #2400
This commit is contained in:
Martin Stein 2017-08-08 14:32:50 +02:00 committed by Christian Helmuth
parent 31af206a8c
commit adaad64fbb
2 changed files with 2 additions and 4 deletions

View File

@ -192,6 +192,7 @@ class Timer::Connection : public Genode::Connection<Session>,
enum { MAX_INTERPOLATION_QUALITY = 3 };
enum { MAX_REMOTE_TIME_LATENCY_US = 500 };
enum { MAX_REMOTE_TIME_TRIALS = 5 };
enum { MIN_FACTOR_LOG2 = 8 };
Genode::Io_signal_handler<Connection> _signal_handler;

View File

@ -85,8 +85,6 @@ void Timer::Connection::_update_real_time()
* Update timestamp-to-time factor and its shift
*/
enum { MAX_FACTOR_SHIFT = sizeof(unsigned long) * 8 };
unsigned factor_shift = _us_to_ts_factor_shift;
unsigned long old_factor = _us_to_ts_factor;
Timestamp max_ts_diff = ~(Timestamp)0ULL >> factor_shift;
@ -138,8 +136,7 @@ void Timer::Connection::_update_real_time()
* raise the shift successively to get as much precision as possible.
*/
Timestamp ts_diff_shifted = ts_diff << factor_shift;
while (ts_diff_shifted <= min_ts_diff_shifted &&
factor_shift < MAX_FACTOR_SHIFT)
while (ts_diff_shifted < us_diff << MIN_FACTOR_LOG2)
{
factor_shift++;
ts_diff_shifted <<= 1;