xref: /freebsd/contrib/ntp/util/hist.c (revision d184218c)
1 /*
2  * This program can be used to calibrate the clock reading jitter of a
3  * particular CPU and operating system. It first tickles every element
4  * of an array, in order to force pages into memory, then repeatedly calls
5  * gettimeofday() and, finally, writes out the time values for later
6  * analysis. From this you can determine the jitter and if the clock ever
7  * runs backwards.
8  */
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 #include "ntp_types.h"
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 
19 #define NBUF 100001		/* size of basic histogram */
20 #define NSRT 20000		/* size of overflow histogram */
21 #define NCNT (600 * 1000000)	/* sample interval (us) */
22 
23 int col P((long *, long *));
24 
25 int
26 main(
27 	int argc,
28 	char *argv[]
29 	)
30 {
31 	struct timeval ts, tr, tp;
32 	struct timezone tzp;
33 	int i, j, n;
34 	long t, u, v, w, gtod[NBUF], ovfl[NSRT];
35 
36 	/*
37 	 * Force pages into memory
38 	 */
39 	for (i = 0; i < NBUF; i++)
40 	    gtod[i] = 0;
41 	for (i = 0; i < NSRT; i++)
42 	    ovfl[i] = 0;
43 
44 	/*
45 	 * Construct histogram
46 	 */
47 	n = 0;
48 	gettimeofday(&ts, &tzp);
49 	t = ts.tv_sec * 1000000 + ts.tv_usec;
50 	v = t;
51 	while (1) {
52 		gettimeofday(&tr, &tzp);
53 		u = tr.tv_sec * 1000000 + tr.tv_usec;
54 		if (u - v > NCNT)
55 		    break;
56 		w = u - t;
57 		if (w <= 0) {
58 /*
59 			printf("error <= 0 %ld %d %d, %d %d\n", w, ts.tv_sec,
60 			       ts.tv_usec, tr.tv_sec, tr.tv_usec);
61 */
62 		} else if (w > NBUF - 1) {
63 			ovfl[n] = w;
64 			if (n < NSRT - 1)
65 			    n++;
66 		} else {
67 			gtod[w]++;
68 		}
69 		ts = tr;
70 		t = u;
71 	}
72 
73 	/*
74 	 * Write out histogram
75 	 */
76 	for (i = 0; i < NBUF - 1; i++) {
77 		if (gtod[i] > 0)
78 		    printf("%ld %ld\n", i, gtod[i]);
79 	}
80 	if (n == 0)
81 	    return;
82 	qsort(
83 #ifdef QSORT_USES_VOID_P
84 	    (void *)
85 #else
86 	    (char *)
87 #endif
88 	    ovfl, (size_t)n, sizeof(long), col);
89 	w = 0;
90 	j = 0;
91 	for (i = 0; i < n; i++) {
92 		if (ovfl[i] != w) {
93 			if (j > 0)
94 			    printf("%ld %ld\n", w, j);
95 			w = ovfl[i];
96 			j = 1;
97 		} else
98 		    j++;
99 	}
100 	if (j > 0)
101 	    printf("%ld %ld\n", w, j);
102 
103 	exit(0);
104 }
105 
106 int
107 col(
108 	long *x,
109 	long *y
110 	)
111 {
112 	return (*x - *y);
113 }
114