#include #include #include #include #include #include #include #define rdtsc(low,high) \ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) #define rdtscl(low) \ __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") #define rdtscll(val) \ __asm__ __volatile__("rdtsc" : "=A" (val)) #define LOOPS 100.0 int main(int argc, char **argv) { int c; unsigned long long start, end, tps = 0; double cal; double max=0,min=0,avg=0; int i; pid_t pid; struct sched_param sp; double sleeptime; unsigned long sec,nsec; sleeptime = 0.01; sec = sleeptime; nsec = (sleeptime-sec) * 1000000000; pid = getpid(); memset(&sp,0,sizeof(sp)); sp.sched_priority = sched_get_priority_max(SCHED_FIFO); sched_setscheduler(pid,SCHED_FIFO,&sp); while ((c=getopt(argc,argv,"c:")) != -1) { switch (c) { case 'c': tps = strtoll(optarg,NULL,10); break; default: exit(0); } } if (!tps) { printf("starting calibrate\n"); rdtscll(start); sleep(8); rdtscll(end); tps = end - start; tps >>= 3; printf("finished calibrate: "); } else { printf("passed in calibrate: "); } cal = tps; cal /= 1000000.0; printf("%.4fMHz %llu\n",cal,tps); for (i=0; i < LOOPS; i++) { struct timespec req = { sec, nsec }; unsigned long long t; rdtscll(start); nanosleep(&req,NULL); rdtscll(end); t = end - start; cal = t; cal /= (double)tps; if (!i || cal > max) max = cal; if (!i || cal < min) min = cal; avg += cal; } avg /= LOOPS; printf("time slept: %.9f sec: %lu nsec: %lu\n",sleeptime,sec,nsec); printf("max: %.9f\n",max); printf("min: %.9f\n",min); printf("avg: %.9f\n",avg); printf("greatest time over: %.3f usecs\n",(max-sleeptime)*1000000.0); if (min > sleeptime) { printf("never ran under (good!)\n"); } else { printf("Ran under!!! (by %.9f) nsecs\n",sleeptime-min); } if (avg > sleeptime) printf("average time over: %.3f usecs\n",(avg-sleeptime)*1000000.0); else printf("average time ran under???\n"); exit(0); }