#include <stdio.h>
#include <sys/time.h>

typedef long long int64;
typedef unsigned long long uint64;
typedef long int32;
typedef unsigned long uint32;

#define TIMEDIFF(a, b) (((a).tv_sec - (b).tv_sec)*1000000 + ((a).tv_usec - (b).tv_usec))

int main(int argc, char **argv, char **arge) {
    struct timeval start, end, prev, cur;
    int64 i;
    int64 time_elapsed = 0;
    int32 duration;
    uint64 loop_count = 0;
    static int64 timings[32];
    
    if (argc != 2 || !sscanf(argv[1], "%ld", &duration) || duration < 0) {
        printf("Usage: test_gettimeofday_monotonic seconds\n");
        return 1;
    }
    uint64 end_time = 1000000ll*duration;

    gettimeofday(&start, 0);
    cur = start;

    while (time_elapsed < end_time) {
       prev = cur;
       gettimeofday(&cur, 0);

       long diff = TIMEDIFF(cur, prev);
       if (diff < 0) {
           printf("Time warp: %ld < 0 => %ld.%ld < %ld.%ld\n",
              diff, cur.tv_sec, cur.tv_usec, prev.tv_sec, prev.tv_usec);
           return -1;
       }
       int bits = 0;
       while (diff) {
          diff >>= 1;
          bits++;
       }
       timings[bits]++;
       loop_count++;
       time_elapsed = TIMEDIFF(cur, start);
    }
    gettimeofday(&end, 0);
    
    printf("Per loop: %0.2f ns\n",
        ((double) TIMEDIFF(end, start))*1000/loop_count);
    printf("%9s: %10s %9s\n", "usec", "count", "percent");
    
    int found = 0;
    for (i = 31; i >= 0; i--) {
        if (found || timings[i]) {
            found = 1;
            printf("%9ld: %10lld %8.5f%%\n", 1l<<i>>1, timings[i],
                ((double)timings[i])*100/loop_count);
        }
    }
    return 0;
}
