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