From 73d18261dcd547ea627a92d85e711e2281775f46 Mon Sep 17 00:00:00 2001 From: Christian Helmuth <christian.helmuth@genode-labs.com> Date: Mon, 10 Jun 2024 16:35:22 +0200 Subject: [PATCH] Fix calculation in timer_ticks_to_us() Added missing factoring of the upper-half division remainder into the lower-half calculation. Fixes #5243 --- repos/base/include/drivers/timer/util.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/repos/base/include/drivers/timer/util.h b/repos/base/include/drivers/timer/util.h index 190eac3778..d161d35a9f 100644 --- a/repos/base/include/drivers/timer/util.h +++ b/repos/base/include/drivers/timer/util.h @@ -28,7 +28,9 @@ namespace Genode { * to time with microseconds precision. Thus, we split the input in two and * translate both parts separately. This way, we can raise precision by * shifting the values to their optimal bit position. Afterwards, the - * results are shifted back and merged together again. + * results are shifted back and merged together again. Note, the remainder + * of the upper-half division is factored into the lower-half calculation + * (as upper-half value). * * Please ensure that the assertion * "ticks_per_ms >= TIMER_MIN_TICKS_PER_MS" is true when calling this @@ -45,10 +47,15 @@ namespace Genode { MSB_RSHIFT = 10, LSB_LSHIFT = HALF_WIDTH - MSB_RSHIFT, }; - RESULT_T const msb = ((((ticks & MSB_MASK) >> MSB_RSHIFT) - * 1000) / ticks_per_ms) << MSB_RSHIFT; - RESULT_T const lsb = ((((ticks & LSB_MASK) << LSB_LSHIFT) - * 1000) / ticks_per_ms) >> LSB_LSHIFT; + /* upper half */ + RESULT_T const msb0 = ((ticks & MSB_MASK) >> MSB_RSHIFT) * 1000; + RESULT_T const msb = (msb0 / ticks_per_ms) << MSB_RSHIFT; + RESULT_T const rem = (msb0 % ticks_per_ms) << MSB_RSHIFT; + /* lower half */ + RESULT_T const lsb0 = ((ticks & LSB_MASK) << LSB_LSHIFT) * 1000 + + (rem << LSB_LSHIFT); + RESULT_T const lsb = (lsb0 / ticks_per_ms) >> LSB_LSHIFT; + return msb + lsb; } }