/* * Test SIGALRM. On many systems, requesting SIGALRM at 100Hz actually * delivers it at 50Hz - I suspect they're not capable of generating a * signal on every clock tick. */ #include #include #include #include #include #include #include static volatile sig_atomic_t n; static volatile int p_r; static volatile int p_w; static struct timeval stv1; static struct timeval stv2; static void catch_sig(int sig) { struct timeval tv; struct itimerval itv; (void)sig; n ++; if (n == 1) { gettimeofday(&tv,0); stv1 = tv; } if (n == 101) { gettimeofday(&tv,0); stv2 = tv; itv.it_value.tv_sec = 0; itv.it_value.tv_usec = 0; itv.it_interval = itv.it_value; setitimer(ITIMER_REAL,&itv,0); write(p_w,&stv1,sizeof(stv1)); write(p_w,&stv2,sizeof(stv2)); } } static void readall(int fd, void *buf, int len) { char *bp; int n; bp = buf; while (len > 0) { n = read(fd,bp,len); if (n < 0) { if (errno == EINTR) continue; fprintf(stderr,"read: %s\n",strerror(errno)); exit(1); } if (n == 0) { fprintf(stderr,"read unexpected EOF\n"); exit(1); } bp += n; len -= n; } } int main(void) { struct itimerval itv; struct sigaction sa; struct timeval tv1; struct timeval tv2; int p[2]; if (pipe(&p[0]) < 0) { fprintf(stderr,"pipe; %s\n",strerror(errno)); exit(1); } p_r = p[0]; p_w = p[1]; sa.sa_handler = &catch_sig; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGALRM,&sa,0); n = 0; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 10000; itv.it_value = itv.it_interval; setitimer(ITIMER_REAL,&itv,0); readall(p_r,&tv1,sizeof(tv1)); readall(p_r,&tv2,sizeof(tv2)); printf("%g Hz\n", 1e8 / ( ((tv2.tv_sec * 1000000ULL) + tv2.tv_usec) - ((tv1.tv_sec * 1000000ULL) + tv1.tv_usec) ) ); return(0); }