File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / util / jitter.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 7 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    1: /*
    2:  * This program can be used to calibrate the clock reading jitter of a
    3:  * particular CPU and operating system. It first tickles every element
    4:  * of an array, in order to force pages into memory, then repeatedly
    5:  * reads the system clock and, finally, writes out the time values for
    6:  * later analysis. From this you can determine the jitter and if the
    7:  * clock ever runs backwards.
    8:  */
    9: 
   10: #ifdef HAVE_CONFIG_H
   11: # include <config.h>
   12: #endif
   13: 
   14: #include <stdio.h>
   15: #include <sys/time.h>
   16: #include <stdlib.h>
   17: #include "jitter.h"
   18: 
   19: #define NBUF	800002
   20: #define FRAC	4294967296.		/* a bbbbillion */
   21: #define JAN_1970 2208988800UL		/* Unix base epoch */
   22: #define CLOCK_GETTIME			/* Solaris hires clock */
   23: 
   24: int debug;
   25: char progname[10];
   26: double sys_residual;
   27: double average;
   28: void sys_gettime(l_fp *);
   29: 
   30: int
   31: main(
   32: 	int argc,
   33: 	char *argv[]
   34: 	)
   35: {
   36: 	l_fp tr;
   37: 	int i, j;
   38: 	double dtemp, gtod[NBUF];
   39: 
   40: 	/*
   41: 	 * Force pages into memory
   42: 	 */
   43: 	for (i = 0; i < NBUF; i ++)
   44: 	    gtod[i] = 0;
   45: 
   46: 	/*
   47: 	 * Construct gtod array
   48: 	 */
   49: 	for (i = 0; i < NBUF; i ++) {
   50: 		get_systime(&tr);
   51: 		LFPTOD(&tr, gtod[i]);
   52: 	}
   53: 
   54: 	/*
   55: 	 * Write out gtod array for later processing with Matlab
   56: 	 */
   57: 	average = 0;
   58: 	for (i = 0; i < NBUF - 2; i++) {
   59: 		gtod[i] = gtod[i + 1] - gtod[i];
   60: 		printf("%13.9f\n", gtod[i]);
   61: 		average += gtod[i];
   62: 	}
   63: 
   64: 	/*
   65: 	 * Sort the gtod array and display deciles
   66: 	 */
   67: 	for (i = 0; i < NBUF - 2; i++) {
   68: 		for (j = 0; j <= i; j++) {
   69: 			if (gtod[j] > gtod[i]) {
   70: 				dtemp = gtod[j];
   71: 				gtod[j] = gtod[i];
   72: 				gtod[i] = dtemp;
   73: 			}
   74: 		}
   75: 	}
   76: 	average = average / (NBUF - 2);
   77: 	fprintf(stderr, "Average %13.9f\n", average);
   78: 	fprintf(stderr, "First rank\n");
   79: 	for (i = 0; i < 10; i++)
   80: 		fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
   81: 	fprintf(stderr, "Last rank\n");
   82: 	for (i = NBUF - 12; i < NBUF - 2; i++)
   83: 		fprintf(stderr, "%2d %13.9f\n", i, gtod[i]);
   84: 	exit(0);
   85: }
   86: 
   87: 
   88: /*
   89:  * get_systime - return system time in NTP timestamp format.
   90:  */
   91: void
   92: get_systime(
   93: 	l_fp *now		/* system time */
   94: 	)
   95: {
   96: 	double dtemp;
   97: 
   98: #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_GETCLOCK)
   99: 	struct timespec ts;	/* seconds and nanoseconds */
  100: 
  101: 	/*
  102: 	 * Convert Unix clock from seconds and nanoseconds to seconds.
  103: 	 */
  104: # ifdef HAVE_CLOCK_GETTIME
  105: 	clock_gettime(CLOCK_REALTIME, &ts);
  106: # else
  107: 	getclock(TIMEOFDAY, &ts);
  108: # endif
  109: 	now->l_i = ts.tv_sec + JAN_1970;
  110: 	dtemp = ts.tv_nsec / 1e9;
  111: 
  112: #else /* HAVE_CLOCK_GETTIME || HAVE_GETCLOCK */
  113: 	struct timeval tv;	/* seconds and microseconds */
  114: 
  115: 	/*
  116: 	 * Convert Unix clock from seconds and microseconds to seconds.
  117: 	 */
  118: 	gettimeofday(&tv, NULL);
  119: 	now->l_i = tv.tv_sec + JAN_1970;
  120: 	dtemp = tv.tv_usec / 1e6;
  121: 
  122: #endif /* HAVE_CLOCK_GETTIME || HAVE_GETCLOCK */
  123: 
  124: 	/*
  125: 	 * Renormalize to seconds past 1900 and fraction.
  126: 	 */
  127: 	dtemp += sys_residual;
  128: 	if (dtemp >= 1) {
  129: 		dtemp -= 1;
  130: 		now->l_i++;
  131: 	} else if (dtemp < -1) {
  132: 		dtemp += 1;
  133: 		now->l_i--;
  134: 	}
  135: 	dtemp *= FRAC;
  136: 	now->l_uf = (u_int32)dtemp;
  137: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>