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