3b1 real time clock runs fast

Bill Mayhew wtm at neoucom.UUCP
Sat Feb 11 11:10:48 AEST 1989


It seems to be an endemic phenomenon among Unix PCs that the kernel
gains time at the rate of about a minute per week.  It sort of
louses up one's uucp schedule on a busy machine after a couple of
weeks.

What is interesting is that the battery-backed RTC chip seems to
keep quite good time.  /etc/clockupd.wk is run from the crontab
every Sunday morning at 3:00 AM, thus ensuring that that the RTC
chip accruately relfects the kernel's incorrect notion of time;
keeping a reboot from restoring correct time.

In actuality, the clockupd.wk is supposed to make sure that the RTC
chip gets switched over to daylight savings time, as the kernel is
smart enough to know about savings time, but the RTC chip isn't.

BUT... there is a syslocal (2) call that allows you to read the RTC
chip.  What I do is read the chip clock on Wednesdays and Sundays
at midnight, waiting until the seconds are at 00, then I execl
/bin/date to set the kernel and (also unavoidably) the RTC chip.
The RTC chip probably loses 50 to 100 mS per invokation of my
program, but that is nothing compared to the 1 minute/week that the
kernel gains!

I'll attach a very quick 'n dirty c program I wrote that
accomplishes the fix.  Note that I busy-wait for the RTC to come
around to 00, but what the heck, it's only about two minutes a
week!

------------------- cut here for fixtime.c ----------------------

/********************************************
 * fixtime.c                                *
 * Bill Mayhew  wtm at impulse.UUCP  Jan. 1989 *
 *                                          *
 * Target machine: AT&T Unix PC / 7300      *
 * Target O/S: Unix relase 3.51             *
 *                                          *
 * This program should be compiled and run  *
 * from your crontab biweekly   (at 00:01?) *
 * in order to keep the kernel's notion of  *
 * time in sync with the rtc battery clock  *
 * chip.  A 60 second sleep is included at  *
 * start-up to avoid recursion of crontab   *
 * re-read.                                 *
 ********************************************/
#include <stdio.h>
#include <sys/syslocal.h>
#include <sys/rtc.h>

main(argc,argv)
  char *argv[];
  int argc;


{
    struct rtc now;
    char sbuf[16];

    /* avoid possible recursive crontab activations */
    sleep(60);


    /* since /bin/date ignores secs, hang around 'til 00 */
    do {
        syslocal(SYSL_RDRTC,&now);
    }
    while ( now.sec10 | now.sec1 );


    sprintf(sbuf,"%1d%1d%1d%1d%1d%1d%1d%1d\0",
      now.mon10,now.mon1,now.day10,now.day1,now.hr10,
      now.hr1,now.min10,now.min1);


    execl("/bin/date","/bin/date", sbuf,0);


    /* can only reach this code if execl failed; most likely
       because /bin/date is screwed up for some reason */
    fprintf(stderr,"%s: failed to execl(/bin/date).\n",argv[0]);
    return(-1);
}



More information about the Comp.sys.att mailing list