File tree Expand file tree Collapse file tree 1 file changed +15
-2
lines changed Expand file tree Collapse file tree 1 file changed +15
-2
lines changed Original file line number Diff line number Diff line change 19
19
#endif
20
20
#endif
21
21
22
+ /* Calculate "x * n / d" without unnecessary overflow or loss of precision.
23
+ *
24
+ * Reference:
25
+ * https://elixir.bootlin.com/linux/v6.10.7/source/include/linux/math.h#L121
26
+ */
27
+ static inline uint64_t mult_frac (uint64_t x , uint64_t n , uint64_t d )
28
+ {
29
+ const uint64_t q = x / d ;
30
+ const uint64_t r = x % d ;
31
+
32
+ return q * n + r * n / d ;
33
+ }
34
+
22
35
void semu_timer_init (semu_timer_t * timer , uint64_t freq )
23
36
{
24
37
timer -> freq = freq ;
@@ -30,12 +43,12 @@ static uint64_t semu_timer_clocksource(uint64_t freq)
30
43
#if defined(HAVE_POSIX_TIMER )
31
44
struct timespec t ;
32
45
clock_gettime (CLOCKID , & t );
33
- return ( t .tv_sec * freq ) + (t .tv_nsec * freq / 1e9 );
46
+ return t .tv_sec * freq + mult_frac (t .tv_nsec , freq , 1e9 );
34
47
#elif defined(HAVE_MACH_TIMER )
35
48
static mach_timebase_info_data_t t ;
36
49
if (mach_clk .denom == 0 )
37
50
(void ) mach_timebase_info (& t );
38
- return mach_absolute_time () * freq / t . denom * t . numer ;
51
+ return mult_frac ( mach_absolute_time () * freq , t . numer , t . denom ) ;
39
52
#else
40
53
return time (0 ) * freq ;
41
54
#endif
You can’t perform that action at this time.
0 commit comments