The fast timers (microtime())

Ulrich Windl (Ulrich.Windl@rz.uni-regensburg.de)
Fri, 3 May 1996 09:21:14 +0200


I've tested the Pentium fasttimer, too. With almost no load I saw some
periodic strange peaks:

0.000065
0.000064
0.000064
0.015055 <<< This is sample 12514
0.000069
0.000065
0.000118
0.000069
0.000066
0.000065
0.000064
...
0.000064
0.000062
0.000064
0.014667 <<< this is sample 28912 (about 1.5 ticks!)
0.000154
0.000065
0.000064

Negative values are very rare and occur only under heavy disk load
(aic7xxx here).

Examples found:
-0.009964 (about -1 tick!)
-0.009935

Interestingly even under light load (flushing access time of inodes to disk)
a lot of negative, but small values occur:

-0.000003
-0.000012
-0.000015
-0.000012
-0.000013
-0.000015
-0.000012
-0.000016
-0.000014
-0.000016
-0.000012
-0.000012
-0.000014
-0.000014
-0.000014
-0.000012
-0.000015
...
-0.000016
-0.000020
-0.000016
-0.000018
-0.000015
-0.000017
-0.000017
-0.000013
-0.000007

But still, this has nothing to do with my changes to the PLL
code. The microtime() offset is just added to the kernel time. The
kernel time itself shouldn't run backwards unless a adjtime() is in
progrss. Well, adding a tick's value from time to time could be from
adjtimex, but I think the changes should be smaller that one tick's
value. If they aren't, then that's the thing I'm hunting for.

For xntpd the problem still is that the offset varies often more than
+- one tick (0.01s). With the current changes of 1.3.97 it's at least
symmetric around zero. My clock needs a frequency correction of roughly
115ppm.

For reference, here's my test program:

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <linux/timex.h>
#include <linux/mc146818rtc.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>

/*======================================================================*/

void main(void)
{
struct timeval tv, tv0, tdiff;
long diff;
char sign;

fprintf(stderr, "Kernel clock check\n");

gettimeofday(&tv0, NULL);
for ( ;; )
{
gettimeofday(&tv, NULL);
diff = 1000000 * (tv.tv_sec - tv0.tv_sec) +
tv.tv_usec - tv0.tv_usec;
sign = '+';
if ( diff < 0 )
sign = '-', diff = -diff;
tdiff.tv_sec = diff / 1000000;
tdiff.tv_usec = diff % 1000000;
if ( sign == '-' )
printf("%c%ld.%06ld\n", sign, tdiff.tv_sec, tdiff.tv_usec);
tv0 = tv;
fflush(stdout);
}
} /* end main */