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 1919#endif
2020#endif
2121
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+
2235void semu_timer_init (semu_timer_t * timer , uint64_t freq )
2336{
2437 timer -> freq = freq ;
@@ -30,12 +43,12 @@ static uint64_t semu_timer_clocksource(uint64_t freq)
3043#if defined(HAVE_POSIX_TIMER )
3144 struct timespec t ;
3245 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 );
3447#elif defined(HAVE_MACH_TIMER )
3548 static mach_timebase_info_data_t t ;
3649 if (mach_clk .denom == 0 )
3750 (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 ) ;
3952#else
4053 return time (0 ) * freq ;
4154#endif
You can’t perform that action at this time.
0 commit comments