On Tue, Aug 05, 2008 at 03:47:19PM +0200, Alain Guibert wrote: > -1) debug printf()s that it waits for the next full second, instead of > the next odd half second. easy fix > -2) The loop is 100% busy all of the time. It should better begin > sleeping, and then busywait only the last 22 ms. That's lighter on the > processor, and has an unexpected very positive effect: hwclock's > accuracy is less perturbated on a loaded system. Just like if the > scheduler was kind to us because we didn't waste timeslices by tens. I have tried to play with nanosleep() and it's possible minimize the busy wait. See the experimental patch below (it's against Kalev's patch). > -3) The delay loop exits at the good moment exactly, down to the single > microsecond. That's fine. But then, instead of calling RTC_SET_TIME > immediatly, the code calls various functions and subfunctions, > calculates this and that, manipulates tm structs, does debug printf()s, > writes /var/lib/lastdate file, and opens /dev/rtc. When RTC_SET_TIME is > finally called, it's too late by 110 µs in normal mode, upto 500 µs in > --debug mode. I think open the device (that's probably the most expensive) and prepare the other things before the delay loop shouldn't be a problem. Maybe we need something like foo = set_hardware_clock_prepare() do .... while (newhwtime == sethwtime + (int) (tdiff + 0.5)) set_hardware_clock(newhwtime, universal, testing, foo) Karel >From 1f0f2afff28fcbced08c35d5cf7c85794850aa13 Mon Sep 17 00:00:00 2001 From: Karel Zak <kzak@xxxxxxxxxx> Date: Thu, 7 Aug 2008 12:32:00 +0200 Subject: [PATCH] hwclock: use nanosleep() rather than busywait Signed-off-by: Karel Zak <kzak@xxxxxxxxxx> --- hwclock/hwclock.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c index deaf42f..4099811 100644 --- a/hwclock/hwclock.c +++ b/hwclock/hwclock.c @@ -522,6 +522,7 @@ set_hardware_clock_exact(const time_t sethwtime, time_t newhwtime; struct timeval beginsystime, nowsystime; double tdiff; + double resol = 1.0/sysconf(_SC_CLK_TCK); /* nansleep resolution is 1/HZ */ time_resync: gettimeofday(&beginsystime, NULL); @@ -548,6 +549,20 @@ set_hardware_clock_exact(const time_t sethwtime, beginsystime = nowsystime; #endif tdiff = time_diff(nowsystime, refsystime); + if (0.5 - tdiff - resol > 0) { + double sl = 0.5 - tdiff - resol; + struct timespec ns = { + .tv_sec = 0, + .tv_nsec = sl * 1000000000, + }; + if (nanosleep(&ns, NULL) == -1) { + gettimeofday(&nowsystime, NULL); + tdiff = time_diff(nowsystime, beginsystime); + } + else + /* be optimistic is cheaper than gettimeofday() :-) */ + tdiff += sl; + } } while (newhwtime == sethwtime + (int) (tdiff + 0.5)); set_hardware_clock(newhwtime, universal, testing); -- 1.5.5.1 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html