Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ntp / util / jitter.c
blobdbb633bd4dee367001372836e9ef8c9efb81d0d7
1 /* $NetBSD: jitter.c,v 1.2 2003/12/04 16:23:38 drochner Exp $ */
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
7 * reads the system clock and, finally, writes out the time values for
8 * later analysis. From this you can determine the jitter and if the
9 * clock ever runs backwards.
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <stdio.h>
17 #include <sys/time.h>
18 #include <stdlib.h>
19 #include "jitter.h"
21 #define NBUF 80002
22 #define FRAC 4294967296. /* a bbbbillion */
23 #define JAN_1970 2208988800UL /* Unix base epoch */
24 #define CLOCK_GETTIME /* Solaris hires clock */
26 int debug;
27 char progname[10];
28 double sys_residual;
29 double average;
30 void sys_gettime(l_fp *);
32 int
33 main(
34 int argc,
35 char *argv[]
38 l_fp tr;
39 int i, j;
40 double dtemp, gtod[NBUF];
43 * Force pages into memory
45 for (i = 0; i < NBUF; i ++)
46 gtod[i] = 0;
49 * Construct gtod array
51 for (i = 0; i < NBUF; i ++) {
52 get_systime(&tr);
53 LFPTOD(&tr, gtod[i]);
57 * Write out gtod array for later processing with Matlab
59 average = 0;
60 for (i = 0; i < NBUF - 2; i++) {
61 gtod[i] = gtod[i + 1] - gtod[i];
62 printf("%13.9f\n", gtod[i]);
63 average += gtod[i];
67 * Sort the gtod array and display deciles
69 for (i = 0; i < NBUF - 2; i++) {
70 for (j = 0; j <= i; j++) {
71 if (gtod[j] > gtod[i]) {
72 dtemp = gtod[j];
73 gtod[j] = gtod[i];
74 gtod[i] = dtemp;
78 average = average / (NBUF - 2);
79 fprintf(stderr, "Average %13.9f\n", average);
80 fprintf(stderr, "First rank\n");
81 for (i = 0; i < 10; i++)
82 fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
83 fprintf(stderr, "Last rank\n");
84 for (i = NBUF - 12; i < NBUF - 2; i++)
85 fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
86 exit(0);
91 * get_systime - return system time in NTP timestamp format.
93 void
94 get_systime(
95 l_fp *now /* system time */
98 double dtemp;
100 #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETCLOCK)
101 struct timespec ts; /* seconds and nanoseconds */
104 * Convert Unix clock from seconds and nanoseconds to seconds.
106 # ifdef HAVE_CLOCK_GETTIME
107 clock_gettime(CLOCK_REALTIME, &ts);
108 # else
109 getclock(TIMEOFDAY, &ts);
110 # endif
111 now->l_i = ts.tv_sec + JAN_1970;
112 dtemp = ts.tv_nsec / 1e9;
114 #else /* HAVE_CLOCK_GETTIME || HAVE_GETCLOCK */
115 struct timeval tv; /* seconds and microseconds */
118 * Convert Unix clock from seconds and microseconds to seconds.
120 gettimeofday(&tv, NULL);
121 now->l_i = tv.tv_sec + JAN_1970;
122 dtemp = tv.tv_usec / 1e6;
124 #endif /* HAVE_CLOCK_GETTIME || HAVE_GETCLOCK */
127 * Renormalize to seconds past 1900 and fraction.
129 dtemp += sys_residual;
130 if (dtemp >= 1) {
131 dtemp -= 1;
132 now->l_i++;
133 } else if (dtemp < -1) {
134 dtemp += 1;
135 now->l_i--;
137 dtemp *= FRAC;
138 now->l_uf = (u_int32)dtemp;