#include #include #include #include #include #include #include // // Purpose: Test interval virtual timer // Usage: fib -n 2000 >& /dev/null & ... & vtimer-basic # w/ interference // vtimer-basic # w/o interference // Calls: gettimeofday, getrusage, sigemptyset, sigaction, setitimer // Ideas: // o Virtual interval timer (ITIMER_VITUAL) accounts only for time used by process // o Granularity is typically the granularity of the system clock (10 msec). // So, alarm is never triggered early but could be triggered late // o If there is another CPU-intensive process running, our process will only // get 50% of the CPU. // o Examples: // Example 1 (with interference) // clock etime utime stime // 1 2.088 1.010 0 // 2 4.128 2.010 0 DELTA etime = K x DELTA utime + overhead // 3 6.168 3.010 0 where K = 2, the # of running // 4 8.208 4.010 0 processes // 5 10.248 5.010 0 // 6 12.288 6.010 0 // 7 14.328 7.010 0 // 8 16.368 8.010 0 // 9 18.408 9.010 0 // 10 20.448 10.010 0 // 11 22.488 11.010 0 // o Example 2 (without interference) // 1 1.047 1.010 0 // 2 2.087 2.010 0 DELTA etime = DELTA utime + overhead // 3 3.127 3.010 0 // 4 4.167 4.010 0 // 5 5.207 5.010 0 // 6 6.247 6.010 0 // 7 7.287 7.010 0 // 8 8.327 8.010 0 // 9 9.367 9.010 0 // 10 10.407 10.010 0 // 11 11.456 11.010 0 // History: // o 8 Jan 2007 kenw: creation // int ctick; // clock ticks every 1 sec struct timeval ctm; // current time struct timeval otm; // original time struct rusage ru; static void sighandler(int s) { int oerrno; int etime; // elapsed time (msec) time_t utime, stime; // user and system time usage oerrno = errno; ++ctick; gettimeofday(&ctm, 0); etime = 1000*(ctm.tv_sec - otm.tv_sec) + (ctm.tv_usec - otm.tv_usec)/1000; getrusage(RUSAGE_SELF, &ru); utime = 1000*ru.ru_utime.tv_sec + ru.ru_utime.tv_usec/1000; stime = 1000*ru.ru_stime.tv_sec + ru.ru_stime.tv_usec/1000; printf("%d\t%d.%03d\t%d.%03d\t%d\n", ctick, etime/1000, etime%1000, utime/1000, utime%1000, stime); errno = oerrno; } int main(void) { struct sigaction act; struct itimerval val; ctick = 0; act.sa_handler = sighandler; // init SIGVTALRM handler act.sa_flags = 0; if (sigemptyset(&act.sa_mask) || sigaction(SIGVTALRM, &act, NULL)) { perror("Gurk!!! Failed to init SIGVTALRM handler"); exit( 1 ); } val.it_interval.tv_sec = 1; // 1-sec interval val.it_interval.tv_usec = 0; val.it_value = val.it_interval; if (setitimer(ITIMER_VIRTUAL, &val, NULL) == -1) { perror("Gurk!!! Failed to init ITIMER_VIRTUAL"); exit( 1 ); } gettimeofday(&otm, 0); // our epoch while ( 1 ); }