mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
x86/time: reduce rounding errors in calculations
Plain (unsigned) integer division simply truncates the results. The overall errors are smaller though if we use proper rounding. (Extend this to the purely cosmetic aspect of time.c's freq_string(), which before this change I've frequently observed to report e.g. NN.999MHz HPET clock speeds.) While adding the rounding logic, also switch to using an unsigned constant for the other, original half of bus_cycle's calculation. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
6b7860b5d0
commit
a60bb68219
3 files changed
+9
-4
No files matched your search
+3
-1
@@ -1260,8 +1260,10 @@ static int __init calibrate_APIC_clock(void)
|
||||
|
||||
/* set up multipliers for accurate timer code */
|
||||
bus_freq = result*HZ;
|
||||
bus_cycle = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
|
||||
bus_cycle = 1000000000000UL / bus_freq; /* in pico seconds */
|
||||
bus_cycle += (1000000000000UL % bus_freq) * 2 > bus_freq;
|
||||
bus_scale = (1000*262144)/bus_cycle;
|
||||
bus_scale += ((1000 * 262144) % bus_cycle) * 2 > bus_cycle;
|
||||
|
||||
apic_printk(APIC_VERBOSE, "..... bus_scale = %#x\n", bus_scale);
|
||||
/* reset APIC to zero timeout value */
|
||||
|
||||
+2
-2
@@ -799,9 +799,9 @@ u64 __init hpet_setup(void)
|
||||
hpet_resume(hpet_boot_cfg);
|
||||
|
||||
hpet_rate = 1000000000000000ULL; /* 10^15 */
|
||||
(void)do_div(hpet_rate, hpet_period);
|
||||
last = do_div(hpet_rate, hpet_period);
|
||||
|
||||
return hpet_rate;
|
||||
return hpet_rate + (last * 2 > hpet_period);
|
||||
}
|
||||
|
||||
void hpet_resume(u32 *boot_cfg)
|
||||
|
||||
+4
-1
@@ -275,7 +275,10 @@ static char *freq_string(u64 freq)
|
||||
{
|
||||
static char s[20];
|
||||
unsigned int x, y;
|
||||
y = (unsigned int)do_div(freq, 1000000) / 1000;
|
||||
|
||||
if ( do_div(freq, 1000) > 500 )
|
||||
++freq;
|
||||
y = (unsigned int)do_div(freq, 1000);
|
||||
x = (unsigned int)freq;
|
||||
snprintf(s, sizeof(s), "%u.%03uMHz", x, y);
|
||||
return s;
|
||||
|
||||