Fix calculation in timer_ticks_to_us()

Added missing factoring of the upper-half division remainder into the
lower-half calculation.

Fixes #5243
This commit is contained in:
Christian Helmuth 2024-06-10 16:35:22 +02:00 committed by Norman Feske
parent a70354cb18
commit 73d18261dc

View File

@ -28,7 +28,9 @@ namespace Genode {
* to time with microseconds precision. Thus, we split the input in two and * to time with microseconds precision. Thus, we split the input in two and
* translate both parts separately. This way, we can raise precision by * translate both parts separately. This way, we can raise precision by
* shifting the values to their optimal bit position. Afterwards, the * 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 * Please ensure that the assertion
* "ticks_per_ms >= TIMER_MIN_TICKS_PER_MS" is true when calling this * "ticks_per_ms >= TIMER_MIN_TICKS_PER_MS" is true when calling this
@ -45,10 +47,15 @@ namespace Genode {
MSB_RSHIFT = 10, MSB_RSHIFT = 10,
LSB_LSHIFT = HALF_WIDTH - MSB_RSHIFT, LSB_LSHIFT = HALF_WIDTH - MSB_RSHIFT,
}; };
RESULT_T const msb = ((((ticks & MSB_MASK) >> MSB_RSHIFT) /* upper half */
* 1000) / ticks_per_ms) << MSB_RSHIFT; RESULT_T const msb0 = ((ticks & MSB_MASK) >> MSB_RSHIFT) * 1000;
RESULT_T const lsb = ((((ticks & LSB_MASK) << LSB_LSHIFT) RESULT_T const msb = (msb0 / ticks_per_ms) << MSB_RSHIFT;
* 1000) / ticks_per_ms) >> LSB_LSHIFT; 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; return msb + lsb;
} }
} }