1999-12-09 13:01:21 +00:00
|
|
|
/*
|
|
|
|
* This program can be used to calibrate the clock reading jitter of a
|
|
|
|
* particular CPU and operating system. It first tickles every element
|
|
|
|
* of an array, in order to force pages into memory, then repeatedly calls
|
|
|
|
* gettimeofday() and, finally, writes out the time values for later
|
|
|
|
* analysis. From this you can determine the jitter and if the clock ever
|
|
|
|
* runs backwards.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2001-08-29 14:35:15 +00:00
|
|
|
# include <config.h>
|
1999-12-09 13:01:21 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "ntp_types.h"
|
|
|
|
|
2001-08-29 14:35:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
1999-12-09 13:01:21 +00:00
|
|
|
#define NBUF 100001 /* size of basic histogram */
|
|
|
|
#define NSRT 20000 /* size of overflow histogram */
|
|
|
|
#define NCNT (600 * 1000000) /* sample interval (us) */
|
|
|
|
|
2013-12-04 21:33:17 +00:00
|
|
|
int col (long *, long *);
|
1999-12-09 13:01:21 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
main(
|
|
|
|
int argc,
|
|
|
|
char *argv[]
|
|
|
|
)
|
|
|
|
{
|
2008-08-18 14:26:05 +00:00
|
|
|
struct timeval ts, tr, tp;
|
|
|
|
struct timezone tzp;
|
1999-12-09 13:01:21 +00:00
|
|
|
int i, j, n;
|
2008-08-18 14:26:05 +00:00
|
|
|
long t, u, v, w, gtod[NBUF], ovfl[NSRT];
|
1999-12-09 13:01:21 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Force pages into memory
|
|
|
|
*/
|
|
|
|
for (i = 0; i < NBUF; i++)
|
|
|
|
gtod[i] = 0;
|
|
|
|
for (i = 0; i < NSRT; i++)
|
|
|
|
ovfl[i] = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Construct histogram
|
|
|
|
*/
|
|
|
|
n = 0;
|
2008-08-18 14:26:05 +00:00
|
|
|
gettimeofday(&ts, &tzp);
|
|
|
|
t = ts.tv_sec * 1000000 + ts.tv_usec;
|
1999-12-09 13:01:21 +00:00
|
|
|
v = t;
|
|
|
|
while (1) {
|
2008-08-18 14:26:05 +00:00
|
|
|
gettimeofday(&tr, &tzp);
|
|
|
|
u = tr.tv_sec * 1000000 + tr.tv_usec;
|
1999-12-09 13:01:21 +00:00
|
|
|
if (u - v > NCNT)
|
|
|
|
break;
|
|
|
|
w = u - t;
|
|
|
|
if (w <= 0) {
|
|
|
|
/*
|
|
|
|
printf("error <= 0 %ld %d %d, %d %d\n", w, ts.tv_sec,
|
|
|
|
ts.tv_usec, tr.tv_sec, tr.tv_usec);
|
|
|
|
*/
|
|
|
|
} else if (w > NBUF - 1) {
|
|
|
|
ovfl[n] = w;
|
|
|
|
if (n < NSRT - 1)
|
|
|
|
n++;
|
|
|
|
} else {
|
|
|
|
gtod[w]++;
|
|
|
|
}
|
2008-08-18 14:26:05 +00:00
|
|
|
ts = tr;
|
1999-12-09 13:01:21 +00:00
|
|
|
t = u;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write out histogram
|
|
|
|
*/
|
|
|
|
for (i = 0; i < NBUF - 1; i++) {
|
|
|
|
if (gtod[i] > 0)
|
|
|
|
printf("%ld %ld\n", i, gtod[i]);
|
|
|
|
}
|
|
|
|
if (n == 0)
|
|
|
|
return;
|
2008-08-18 14:26:05 +00:00
|
|
|
qsort(
|
|
|
|
#ifdef QSORT_USES_VOID_P
|
|
|
|
(void *)
|
|
|
|
#else
|
|
|
|
(char *)
|
|
|
|
#endif
|
|
|
|
ovfl, (size_t)n, sizeof(long), col);
|
1999-12-09 13:01:21 +00:00
|
|
|
w = 0;
|
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
if (ovfl[i] != w) {
|
|
|
|
if (j > 0)
|
|
|
|
printf("%ld %ld\n", w, j);
|
|
|
|
w = ovfl[i];
|
|
|
|
j = 1;
|
|
|
|
} else
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
if (j > 0)
|
|
|
|
printf("%ld %ld\n", w, j);
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
col(
|
2008-08-18 14:26:05 +00:00
|
|
|
long *x,
|
|
|
|
long *y
|
1999-12-09 13:01:21 +00:00
|
|
|
)
|
|
|
|
{
|
|
|
|
return (*x - *y);
|
|
|
|
}
|