From: Karel Zak Date: Mon, 19 Mar 2007 23:32:37 +0000 (+0100) Subject: hwclock: fix --systohc sets clock 0.5 seconds slow X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99c392d8ba163e35b9d562dd4bcf7dd476ad3573;p=util-linux hwclock: fix --systohc sets clock 0.5 seconds slow quote from rh150493: The kernel code, when setting the BIOS clock notes that the clock time ticks to the next second 0.5 seconds after adjusting it (see linux/arch/i386/kernel/time.c). hwclock --systohc sets the CMOS clock at the 1 second boundry and thus causes the clock to be wrong by 500ms each time it is reset. If the clock is set every shutdown then the clock will have a reboot-count related drift as well as the natural drift problems of the clock. Note that this also mucks up the drift calculations, of course. Signed-off-by: Karel Zak --- diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c index 9731dadf..820c388d 100644 --- a/hwclock/hwclock.c +++ b/hwclock/hwclock.c @@ -517,14 +517,19 @@ set_hardware_clock_exact(const time_t sethwtime, "Delaying further to reach the next full second.\n"), time_diff(beginsystime, refsystime)); - /* Now delay some more until Hardware Clock time newhwtime arrives */ + /* + * Now delay some more until Hardware Clock time newhwtime arrives. The -500 + * ms is because the Hardware Clock always sets to your set time plus 500 ms + * (because it is designed to update to the next second precisely 500 ms + * after you finish the setting). + */ do { float tdiff; gettimeofday(&nowsystime, NULL); tdiff = time_diff(nowsystime, beginsystime); if (tdiff < 0) goto time_resync; /* probably time was reset */ - } while (time_diff(nowsystime, refsystime) < newhwtime - sethwtime); + } while (time_diff(nowsystime, refsystime) - 0.5 < newhwtime - sethwtime); set_hardware_clock(newhwtime, universal, testing); } diff --git a/tests/ts-hwclock-systohc b/tests/ts-hwclock-systohc index 522b597f..6171ab30 100755 --- a/tests/ts-hwclock-systohc +++ b/tests/ts-hwclock-systohc @@ -72,5 +72,5 @@ if [ "$DIFF" == "1" ]; then ts_failed "offset is $OFFSET" fi -ts_ok +ts_ok "offset is $OFFSET"