/* * Program to measure high-res timer latency. * */ #include #include #include #include #include #include #include #include #ifndef N_SAMPLES #define N_SAMPLES 100 #endif #define _STR(_S_) #_S_ #define STR(_S_) _STR(_S_) int main(int argc, char *const* argv, char *const* envp) { clockid_t clk = CLOCK_MONOTONIC_RAW; bool do_dump = false; int argn=1; for(; argn < argc; argn+=1) if( argv[argn] != NULL ) if( *(argv[argn]) == '-') switch( *(argv[argn]+1) ) { case 'm': case 'M': clk = CLOCK_MONOTONIC; break; case 'd': case 'D': do_dump = true; break; case '?': case 'h': case 'u': case 'U': case 'H': fprintf(stderr,"Usage: timer_latency [ -m : use CLOCK_MONOTONIC clock (not CLOCK_MONOTONIC_RAW) ; -d : dump timespec contents. N_SAMPLES: " STR(N_SAMPLES) "\n\t" "Calculates average timer latency (minimum time that can be measured) over N_SAMPLES.\n" ); return 0; } struct timespec sample[N_SAMPLES+1]; unsigned int cnt=N_SAMPLES, s=0 ; do { if( 0 != clock_gettime(clk, &sample[s++]) ) { fprintf(stderr,"oops, clock_gettime() failed: %d: '%s'.\n", errno, strerror(errno)); return 1; } }while( --cnt ); clock_gettime(clk, &sample[s]); #define TS2NS(_TS_) ((((unsigned long long)(_TS_).tv_sec)*1000000000ULL) + (((unsigned long long)((_TS_).tv_nsec)))) unsigned long long deltas [ N_SAMPLES ] , t1, t2, sum=0, zd=0 , t_start = TS2NS(sample[0]); for(s=1; s < (N_SAMPLES+1); s+=1) { t1 = TS2NS(sample[s-1]); t2 = TS2NS(sample[s]); if ( t1 > t2 ) { fprintf(stderr,"Inconsistency: %llu %llu %lu.%lu %lu.%lu\n", t1 , t2 , sample[s-1].tv_sec, sample[s-1].tv_nsec , sample[s].tv_sec, sample[s].tv_nsec ); continue; } unsigned long long d =t2-t1; if ( d == 0 ) { if( zd == 0 ) fprintf(stderr, "0 delta!\n"); zd += 1; } deltas[s-1] = d; if(do_dump) fprintf(stderr, "%lu %lu %llu\n", sample[s].tv_sec, sample[s].tv_nsec, d ); } if( zd > 0 ) fprintf(stderr,"%u 0 deltas\n"); for(s = 0; s < N_SAMPLES; s+=1) sum += deltas[s]; fprintf(stderr,"sum: %llu\n",sum); unsigned long long avg_ns = sum / N_SAMPLES; t1=(t2 - t_start); printf("Total time: %1.1llu.%9.9lluS - Average Latency: %1.1llu.%9.9lluS\n", t1 / 1000000000, t1 % 1000000000, avg_ns / 1000000000, avg_ns % 1000000000 ); return 0; }