/* This example shows the amount of time a process will take to run when it causes Overflow floating point exceptions (fpes). The inner loop, loop1, will cause MAX Overflow fpes. The outer loop will loop two times. The first time through the outer loop, Overflow fpes will not be enabled ( the FPU is handling the Overflow fpe ). The second time through the outer loop, Overflow fpes will be enabled ( the process is handling the Overflow fpe ). Notice the time differences spent in user and kernel mode between the two loop iterations. One should avoid raising fpes in general, specifically signaling fpes which cause software to handle the fpe. Here are the results from a test ran on a 100 MHZ IP22 MIPS RISC Processor: cc test4.c -o test4 -lfpe su ./test4 res = inf time spent in system in micro-seconds = 49 time spent in user in micro-seconds = 1517 res = 20.000000 time spent in system in micro-seconds = 2766800 time spent in user in micro-seconds = 563537 */ #include #include #include #include #include #include #include #include #define MAX 10000 /* Max loop iterations */ #define MSPS 1000000 /* Micro Seconds Per Second */ void handler_rout(exception, ret_val) int exception[5]; float ret_val[2]; { switch(exception[_EXCEPTION_TYPE]) { case _OVERFL : ret_val[0] = 20.0; break; } } main() { register float res,max,ten; register int i,q,dts,dtu; struct rusage r1,r2; if ( plock ( PROCLOCK ) != 0 ) perror ( "Failed plock" ) ; if (schedctl(NDPRI, 0, NDPHIMAX) != 0) perror( "Failed schedctl" ) ; max = FLT_MAX; ten = 10.0; for(q=0;q<2;q++) { if ((getrusage(0,&r1)) == -1) { perror("getrusage"); exit(-1); } /* Let's generate some overflows */ i = 0; loop1: res = max*ten; if (i++ < MAX) goto loop1; if ((getrusage(0,&r2)) == -1) { perror("getrusage"); exit(-1); } dtu =((r2.ru_utime.tv_sec*MSPS) + r2.ru_utime.tv_usec) - ((r1.ru_utime.tv_sec*MSPS) + r1.ru_utime.tv_usec); dts =((r2.ru_stime.tv_sec*MSPS) + r2.ru_stime.tv_usec) - ((r1.ru_stime.tv_sec*MSPS) + r1.ru_stime.tv_usec); printf(" res = %f\n",res); printf(" time spent in system in micro-seconds = %d\n",dts); printf(" time spent in user in micro-seconds = %d\n\n",dtu); /* Establish handler_rout() to be the module to handle SIGFPEs */ sigfpe_[_OVERFL].repls = _USER_DETERMINED; handle_sigfpes (_ON, _EN_OVERFL , (void*)handler_rout, 0, 0); } exit(1); }