Annotation of embedaddon/ntp/util/jitter.c, revision 1.1.1.1

1.1       misho       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>