timetest.c revision fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1
1fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <stdlib.h> 2fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <stdio.h> 3fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <unistd.h> 4fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <sys/limits.h> 5fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <sys/time.h> 6fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <time.h> 7fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <errno.h> 8fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 9fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#include <string.h> 10fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 11fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 12fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 13fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåglong long nanotime(void) 14fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg{ 15fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg struct timespec t; 16fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 17fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(clock_gettime(CLOCK_MONOTONIC, &t)) { 18fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg fprintf(stderr,"clock failure\n"); 19fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg exit(1); 20fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 21fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 22fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return (((long long) t.tv_sec) * 1000000000LL) + 23fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg ((long long) t.tv_nsec); 24fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg} 25fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 26fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevågstatic struct timespec ts_sub(struct timespec a, struct timespec b) 27fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg{ 28fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg struct timespec r; 29fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_sec = a.tv_sec - b.tv_sec; 30fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_nsec = a.tv_nsec - b.tv_nsec; 31fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(r.tv_nsec < 0) { 32fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_sec--; 33fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_nsec += 1000 * 1000 * 1000; 34fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 35fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(r.tv_sec < 0 && r.tv_nsec > 0) { 36fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_sec++; 37fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg r.tv_nsec -= 1000 * 1000 * 1000; 38fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 39fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return r; 40fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg} 41fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 42fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevågstatic struct timespec ts_min(struct timespec a, struct timespec b) 43fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg{ 44fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) 45fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return a; 46fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg else 47fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return b; 48fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg} 49fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 50fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevågstatic struct timespec ts_max(struct timespec a, struct timespec b) 51fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg{ 52fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) 53fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return b; 54fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg else 55fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return a; 56fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg} 57fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 58fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevågint main(int argc, char **argv) 59fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg{ 60fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg long long tnow, tlast; 61fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg struct timespec t1, dtmin, dtminp, dtmax; 62fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg int print_interval = 50000; 63fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg int print_countdown = 1; 64fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg int clock_id = CLOCK_MONOTONIC; 65fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmin.tv_sec = INT_MAX; 66fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmin.tv_nsec = 0; 67fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtminp.tv_sec = INT_MAX; 68fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtminp.tv_nsec = 0; 69fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmax.tv_sec = 0; 70fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmax.tv_nsec = 0; 71fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg tlast = 0; 72fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 73fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(argc == 2) { 74fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg clock_id = atoi(argv[1]); 75fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg printf("using clock %d\n", clock_id); 76fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 77fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg clock_gettime(clock_id, &t1); 78fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 79fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg for(;;) { 80fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg struct timespec t, dt; 81fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg clock_gettime(clock_id, &t); 82fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dt = ts_sub(t, t1); 83fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg t1 = t; 84fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmin = ts_min(dtmin, dt); 85fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(dt.tv_sec > 0 || dt.tv_nsec > 0) 86fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtminp = ts_min(dtminp, dt); 87fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(print_countdown != print_interval) 88fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmax = ts_max(dtmax, dt); 89fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(--print_countdown == 0) { 90fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg fprintf(stderr,"%09ld.%09ld, dt %ld.%09ld, min %ld.%09ld, minp %ld.%09ld, max %ld.%09ld\n", 91fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg t.tv_sec, t.tv_nsec, dt.tv_sec, dt.tv_nsec, 92fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmin.tv_sec, dtmin.tv_nsec, dtminp.tv_sec, dtminp.tv_nsec, 93fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg dtmax.tv_sec, dtmax.tv_nsec); 94fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg print_countdown = print_interval; 95fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 96fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 97fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg for(;;) { 98fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg tnow = nanotime(); 99fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg if(tnow < tlast) { 100fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#if 0 101fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg fprintf(stderr,"time went backwards: %lld -> %lld\n", 102fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg tlast, tnow); 103fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg exit(1); 104fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg#endif 105fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg fprintf(stderr,"%lld ROLLBACK\n", tnow); 106fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } else { 107fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg fprintf(stderr,"%lld\n", tnow); 108fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 109fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg tlast = tnow; 110fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg } 111fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg 112fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg return 0; 113fb96abdcfc53dc0c4ff0450c0afd192d6ba570c1Arve Hjønnevåg} 114