Hi Scott, Thanks for this work! I see significant improvement with my test code (see below; obviously focussing quite specificially on one thing). Before your diff (snapshot from a few days ago; OpenBSD 6.9-current (GENERIC.MP) #1: Mon May 3 11:04:25 MDT 2021) I got:
[weerd@pom] $ ./measure Running for 100 loops timeout 800000us min/avg/max/std-dev: 800054/809727.250/810115/1609.611 us timeout 400000us min/avg/max/std-dev: 409668/410000.406/410362/121.568 us timeout 200000us min/avg/max/std-dev: 209421/209997.953/210553/97.505 us timeout 100000us min/avg/max/std-dev: 109818/109997.078/110167/39.038 us timeout 50000us min/avg/max/std-dev: 59887/59995.539/60108/27.651 us timeout 25000us min/avg/max/std-dev: 29648/29993.961/30316/50.629 us timeout 12500us min/avg/max/std-dev: 19910/19994.100/20098/24.265 us timeout 6250us min/avg/max/std-dev: 19932/19994.020/20067/20.760 us timeout 3125us min/avg/max/std-dev: 19806/19993.980/20221/33.121 us timeout 1562us min/avg/max/std-dev: 19519/19993.971/20470/71.215 us timeout 781us min/avg/max/std-dev: 19778/19993.980/20214/35.454 us timeout 390us min/avg/max/std-dev: 19784/19994.029/20188/32.626 us timeout 195us min/avg/max/std-dev: 19891/19994.230/20096/23.237 us timeout 97us min/avg/max/std-dev: 19938/19994.170/20044/17.468 us timeout 48us min/avg/max/std-dev: 19876/19994.010/20115/26.334 us timeout 24us min/avg/max/std-dev: 19535/19994.199/20458/67.628 us timeout 12us min/avg/max/std-dev: 19941/19994.240/20079/18.478 us timeout 6us min/avg/max/std-dev: 19949/19994.150/20051/16.916 us timeout 3us min/avg/max/std-dev: 19880/19994.221/20109/23.377 us timeout 1us min/avg/max/std-dev: 19940/19994.289/20053/17.575 us [I should add that these numbers are from an otherwise mostly idle machine; they improved when my machine was busy building a new kernel] After upgrading my local snap, cvs-up'ing, patching in your diff and building + rebooting into a new kernel: [weerd@pom] $ ./measure Running for 100 loops timeout 800000us min/avg/max/std-dev: 800041/808010.312/810021/2992.553 us timeout 400000us min/avg/max/std-dev: 401639/402001.281/402373/-nan us timeout 200000us min/avg/max/std-dev: 200959/200997.922/201041/-nan us timeout 100000us min/avg/max/std-dev: 100456/100495.977/100533/37.185 us timeout 50000us min/avg/max/std-dev: 50141/50244.809/50351/30.089 us timeout 25000us min/avg/max/std-dev: 28917/30144.590/31396/175.702 us timeout 12500us min/avg/max/std-dev: 20048/20094.420/20143/10.583 us timeout 6250us min/avg/max/std-dev: 10016/10044.260/10084/9.683 us timeout 3125us min/avg/max/std-dev: 9974/10044.060/10140/14.810 us timeout 1562us min/avg/max/std-dev: 10016/10044.190/10078/6.827 us timeout 781us min/avg/max/std-dev: 9964/10044.140/10143/14.516 us timeout 390us min/avg/max/std-dev: 9578/10044.150/10507/66.234 us timeout 195us min/avg/max/std-dev: 9981/10044.170/10122/16.570 us timeout 97us min/avg/max/std-dev: 10010/10044.150/10117/10.721 us timeout 48us min/avg/max/std-dev: 10004/10044.140/10083/10.331 us timeout 24us min/avg/max/std-dev: 10016/10044.220/10078/6.487 us timeout 12us min/avg/max/std-dev: 10014/10044.210/10079/6.802 us timeout 6us min/avg/max/std-dev: 10013/10044.300/10085/9.871 us timeout 3us min/avg/max/std-dev: 10007/10044.030/10090/8.477 us timeout 1us min/avg/max/std-dev: 9980/10044.350/10135/13.301 us (obviously some bug in the std-dev calculation there with the -nan) Thanks again, Paul --- measure.c -------------------------------------------------------- #include <err.h> #include <errno.h> #include <math.h> #include <signal.h> #include <stdio.h> #include <unistd.h> #include <sys/time.h> #define LOOPCOUNT 100 volatile sig_atomic_t trigger; void sighdlr(int signum) { trigger = signum; } int main() { int long long count, d, sum, min, max, tsumsq; long timeout; struct timeval str, end; struct itimerval new_timer; double avg, dev; new_timer.it_interval.tv_sec = 0; new_timer.it_interval.tv_usec = 0; new_timer.it_value.tv_sec = 0; signal(SIGALRM, sighdlr); printf("Running for %d loops\n\n", LOOPCOUNT); for (timeout = 800000; timeout != 0; timeout /= 2) { new_timer.it_value.tv_usec = timeout; min = 1000000000; max = 0; sum = 0; tsumsq = 0; for (count = 0; count != LOOPCOUNT; count++) { trigger = 0; setitimer(ITIMER_REAL, &new_timer, NULL); gettimeofday(&str, NULL); while (trigger == 0) pause(); gettimeofday(&end, NULL); d = (end.tv_sec - str.tv_sec) * 1000000 + \ end.tv_usec - str.tv_usec; sum += d; tsumsq += d * d; if (d < min) min = d; if (d > max) max = d; } avg = (float) sum / count; dev = sqrt((float) tsumsq / count - avg * avg); printf("timeout %7ldus min/avg/max/std-dev: %lld/%.3f/" \ "%lld/%.3f us\n", timeout, min, avg, max, dev); } } ---------------------------------------------------------------------- -- >++++++++[<++++++++++>-]<+++++++.>+++[<------>-]<.>+++[<+ +++++++++++>-]<.>++[<------------>-]<+.--------------.[-] http://www.weirdnet.nl/