A small test below shows the problem with the itimer setting on OL8 (x86_64 / aarch64) % cat sig.c #include<stdio.h> #include <stdlib.h> #include<signal.h> #include <time.h> #include <sys/time.h> #include <string.h> #ifndef MY_TIMER #define MY_TIMER 1000 #endif static time_t start; static int sigprof_cnt = 0; time_t gethrtime (void) { struct timespec tp; time_t rc = 0; int r = clock_gettime (CLOCK_MONOTONIC, &tp); if (r == 0) rc = ((time_t) tp.tv_sec) * 1e9 + (time_t) tp.tv_nsec; return rc; } static void sigprof_handler(int signo, siginfo_t* info, void *context) { if (++sigprof_cnt >= 3) exit(0); static struct itimerval t; memset(&t, 0, sizeof(t)); if (getitimer(ITIMER_PROF, &t) != 0) printf("getitimer failed\n"); printf("sigprof_handler: it_interval.tv_sec=%lld it_interval.tv_usec=%lld\n" " it_value.tv_sec=%lld it_value.tv_usec=%lld\n", (long long) t.it_interval.tv_sec, (long long) t.it_interval.tv_usec, (long long) t.it_value.tv_sec, (long long) t.it_value.tv_usec); } volatile long x; /* temp variable for long calculation */ int main (int argc, char **argv) { long long count = 0; start = gethrtime (); struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction = sigprof_handler; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigemptyset(&sa.sa_mask); if (sigaction(SIGPROF, &sa, NULL) == -1) { perror("sigaction"); return 1; } static struct itimerval timer; memset(&timer, 0, sizeof(timer)); timer.it_interval.tv_usec = MY_TIMER; timer.it_value.tv_usec = MY_TIMER; if (setitimer(ITIMER_PROF, &timer, NULL) != 0) { printf("Timer could not be initialized \n"); return 1; } struct itimerval t; memset(&t, 0, sizeof(t)); if (getitimer(ITIMER_PROF, &t) != 0) { printf("getitimer failed\n"); return 1; } printf("After setitimer: it_interval.tv_sec=%lld it_interval.tv_usec=%lld\n" " it_value.tv_sec=%lld it_value.tv_usec=%lld\n", (long long) t.it_interval.tv_sec, (long long) t.it_interval.tv_usec, (long long) t.it_value.tv_sec, (long long) t.it_value.tv_usec); do { x = 0; for (int j = 0; j < 1000000; j++) x = x + 1; count++; } while (start + 1e9 / 4 > gethrtime ()); printf("count=%lld x=%lld\n", count, x); return 0; } It is from man page: % man setitimer ... setitimer() If either field in new_value.it_value is nonzero, then the timer is arme to initially expire at the specified time. But this is not right on x86_64 and aarch64. I run this test on OL8. On x86_64 / OL8: % gcc -DMY_TIMER=1000 sig.c; ./a.out After setitimer: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=2000 <<<<<< this should be <= 1000 because I set it_value.tv_usec to 1000 in setitimer sigprof_handler: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=23 sigprof_handler: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=27 On aarch64 / OL8: % gcc -DMY_TIMER=1000 sig.c; ./a.out After setitimer: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=5000 <<<<<< Same as on x86_64 sigprof_handler: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=4000 <<<<<< this must be <= 1000 because it_interval.tv_usec is 1000 sigprof_handler: it_interval.tv_sec=0 it_interval.tv_usec=1000 it_value.tv_sec=0 it_value.tv_usec=4000<<<<<< this must be <= 1000 because it_interval.tv_usec is 1000
I believe this issue stems from the fact that on your system the tick interval is 0.004 seconds (4000 microseconds), so setitimer will not be able to accurately work with intervals under that number.