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