Re: [PATCH] hwclock: delay loop in set_hardware_clock_exact

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux