Hello,

 On Monday, September 24, 2007 at 6:06:17 -0400, A. Costa wrote:

> It seems 'adjtimex' is quite clock & CPU dependent;

Yes, of course: adjtimex --adjust operation (and some others) does read
the CMOS clock. On a system busy doing other things, the timings can be
degraded, possibly very much.


> it could check if the CPU was busy before making tests;

And there could be some words about good conditions for such calibration
in the install docs. It may not be completely obvious for everybody.


> or a maximum adjustment, if exceeded, generates an error or else
> triggers some appropriate response.

The NTP community often presents ±500 PPM as the maximum for a sane
motherboard. That would be ±43.2 secs/day. However machines over that do
exist. And can be supported by adjtimex, provided this high rate is
stable. The adjustement of --tick can even help such wild clocks to
become disciplinable by the NTP daemon. What about a simple warning?


We can also try to make adjtimex less sensible to system load. The first
step on this path would be to timestamp more closely the RTC clock beat.
The attached close-timestamping.2.patch does this. On my old and slow
test machine, this reduced from around 80 µs to zero the timestamping
delay. Both for /dev/rtc with interrupt, and the UIP polling method.
This also reduced a little bit the variability of measures. And
marginaly reduced the sensibility to system load. It's only a first
step, though.


James: Could you please also apply the 2nd attached email-free.patch,
which updates my email address in adjtimex.c and ChangeLog. Thanks!


BTW I suspect that in cmos_read_time() the case where we are using
/dev/rtc but ioctl(RTC_UIE_ON) fails, just can't work: It will block
forever in read() later. Can't verify for sure, because on my machines
the ioctl(RTC_UIE_ON) succeeds.


Alain.
Timestamp the tick of the CMOS clock at the closest possible,
for better accuracy and lower dispersion of measures.
Signed-off-by: Alain Guibert <[EMAIL PROTECTED]>


diff -prud adjtimex-1.22/adjtimex.c adjtimex-1.22.mod/adjtimex.c
--- adjtimex-1.22/adjtimex.c    Mon Oct  1 00:15:15 2007
+++ adjtimex-1.22.mod/adjtimex.c        Mon Oct  1 00:56:41 2007
@@ -151,7 +151,7 @@ static inline unsigned char inb (short p
 static void cmos_init ();
 static inline int cmos_read_bcd (int addr);
 static void cmos_read_time (time_t *cmos_timep, double *sysp);
-static void busy_wait(void);
+static void busy_wait(struct timeval *timestamp);
 static void compare(void);
 static void failntpdate();
 static void reset_time_status(void);
@@ -607,7 +607,7 @@ cmos_read_time (time_t *cmos_timep, doub
            fprintf(stdout, 
                    "/dev/rtc doesn't allow user access to update interrupts\n"
                    " - using busy wait instead\n");
-         busy_wait();
+         busy_wait(&now);
        }
       {
        unsigned long dummy;
@@ -615,7 +615,8 @@ cmos_read_time (time_t *cmos_timep, doub
        
        do {
          rc = read(cmos_fd, &dummy, sizeof(dummy));
-         
+         gettimeofday(&now, NULL);
+
          if (rc == -1)
            {
              perror("read() from /dev/rtc to wait for clock tick failed");
@@ -638,11 +639,11 @@ cmos_read_time (time_t *cmos_timep, doub
     }
   else
     {
-      busy_wait();
       /* The "do" loop is "low-risk programming" */
       /* In theory it should never run more than once */
       do
        {
+         busy_wait(&now);
          tm.tm_sec = cmos_read_bcd (0);
          tm.tm_min = cmos_read_bcd (2);
          tm.tm_hour = cmos_read_bcd (4);
@@ -661,9 +662,6 @@ cmos_read_time (time_t *cmos_timep, doub
     }
   tm.tm_isdst = -1;            /* don't know whether it's summer time */
 
-
-  /* fetch system time immediately */
-  gettimeofday (&now, NULL);
   
   if (universal)
     cmos_time = mkgmtime(&tm);
@@ -742,8 +740,10 @@ cmos_read_time (time_t *cmos_timep, doub
   *sysp = now.tv_sec + .000001*now.tv_usec;
 }
 
+
+/* busywait for UIP fall and timestamp this event */
 static void
-busy_wait()
+busy_wait(struct timeval *timestamp)
 {
   long i;
   
@@ -757,8 +757,10 @@ busy_wait()
   /* Wait for fall.... (must try at least 2.228 ms) */
   
   for (i = 0; i < 1000000; i++)
-    if (!(CMOS_READ (10) & 0x80))
+    if (!(CMOS_READ (10) & 0x80)) {
+      gettimeofday(timestamp, NULL);
       break;
+    }
 }
 
 static inline void 
Update Alain Guibert's email address in code and ChangeLog.
Signed-off-by: Alain Guibert <[EMAIL PROTECTED]>


diff -prud adjtimex-1.22.orig/ChangeLog adjtimex-1.22/ChangeLog
--- adjtimex-1.22.orig/ChangeLog        Sun Sep 23 18:27:04 2007
+++ adjtimex-1.22/ChangeLog     Mon Oct  1 14:37:09 2007
@@ -72,7 +72,7 @@
        * adjtimex.c (compare): Adjust CMOS times by + or - 60 min, if
        that brings them closer to the system time.  If they still differ
        by more than 6 min, then print a warning and suppress logging.
-       (Thanks to Alain Guibert <derogaton at oreka.com> for noting that
+       (Thanks to Alain Guibert <alguibert at free.fr> for noting that
        summer time start/end can impact the log.)
 
 2006-05-21  James R. Van Zandt  <jrv at debian.org>
@@ -92,8 +92,8 @@
 
        * adjtimex.c (compare): in "compare" or "adjust", return
        immediately after printing last result (instead of sleeping an
-       extra $interval seconds) (Thanks to Alain Guibert <derogaton at
-       oreka.com>)
+       extra $interval seconds) (Thanks to Alain Guibert <alguibert at
+       free.fr>)
 
 2004-09-11  James R. Van Zandt  <jrv at debian.org>
 
@@ -119,12 +119,12 @@
        * adjtimex.c (usage): Don't split strings across lines.
        (main): --reset switch enables resetting of status (no longer
        default action, because it's not needed by recent kernels) (thanks
-       to Alain Guibert <derogaton at oreka.com>)
+       to Alain Guibert <alguibert at free.fr>)
 
 2004-04-09  James R. Van Zandt  <jrv at debian.org>
 
        * adjtimex.c (longopt): --status switch sets clock status
-       (courtesy of Alain Guibert <derogaton at oreka.com>
+       (courtesy of Alain Guibert <alguibert at free.fr>
        
 2004-04-04  James R. Van Zandt  <jrv at debian.org>
 
diff -prud adjtimex-1.22.orig/adjtimex.c adjtimex-1.22/adjtimex.c
--- adjtimex-1.22.orig/adjtimex.c       Sun Sep 23 18:49:10 2007
+++ adjtimex-1.22/adjtimex.c    Mon Oct  1 14:34:11 2007
@@ -677,7 +677,7 @@ cmos_read_time (time_t *cmos_timep, doub
     {
       /* There are clues to whether the CMOS clock is set to
         summer time, which could be used as suggested by Alain
-        Guibert <derogaton at oreka.com>:
+        Guibert <alguibert at free.fr>:
         
         Since version 2.5, hwclock records CMOS timezone UTC or
         LOCAL as 1st item of 3rd line of /etc/adjtime. If it's

Reply via email to