1 /* $NetBSD: jitter.c,v 1.2 2003/12/04 16:23:38 drochner Exp $ */
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.
22 #define FRAC 4294967296. /* a bbbbillion */
23 #define JAN_1970 2208988800UL /* Unix base epoch */
24 #define CLOCK_GETTIME /* Solaris hires clock */
30 void sys_gettime(l_fp
*);
40 double dtemp
, gtod
[NBUF
];
43 * Force pages into memory
45 for (i
= 0; i
< NBUF
; i
++)
49 * Construct gtod array
51 for (i
= 0; i
< NBUF
; i
++) {
57 * Write out gtod array for later processing with Matlab
60 for (i
= 0; i
< NBUF
- 2; i
++) {
61 gtod
[i
] = gtod
[i
+ 1] - gtod
[i
];
62 printf("%13.9f\n", 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
]) {
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
]);
91 * get_systime - return system time in NTP timestamp format.
95 l_fp
*now
/* system time */
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
);
109 getclock(TIMEOFDAY
, &ts
);
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
;
133 } else if (dtemp
< -1) {
138 now
->l_uf
= (u_int32
)dtemp
;