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