Hi, If I set the SCHED_FIFO schedular, register a SIGALRM handler, set an alarm() and consume 100% of CPU time on an isolated CPU (IOW, never leave running/runable), the signal will never arrive in userspace. According to /proc/timer_list the expiration time will become a negative value. But if I synchronously send a SIGALRM via kill, it will immediately arrive. Even a sched_yield() in the busy loop won't help. In order to get the signal, I have to leave running/runable with usleep(). Now I'm not sure if this behaviour is intended for some reason or if it's a bug. Please find a minimal example attached. Run it on an isolated CPU with taskset. Reproduceable with 4.14.x-rt and latest -rt. Not reproducable with mainline Linux and PREEMPT. Thanks Ralf (How I found this: I'm currently using stress-ng as a stressor for some cyclictest measurements. stress-ng fork()s stressors. Stressors can be parameterised by a timeout, which is implemented as alarm(). The timeout will never occur, as stressors never leave Running/Runable.)
#include <unistd.h> #include <stdio.h> #include <signal.h> #include <stdbool.h> #include <sys/types.h> #include <sys/wait.h> #include <sched.h> #include <string.h> static volatile bool stop; static void alarm_handler(int sig) { printf("Woof woof!\n"); stop = true; } int main(void) { struct sched_param sp; int ret; memset(&sp, 0, sizeof(sp)); sp.sched_priority = 12; ret = sched_setscheduler(0, SCHED_FIFO, &sp); if (ret != 0) { printf("Error setting scheduler\n"); return -1; } if (signal(SIGALRM, alarm_handler) == SIG_ERR) { printf("\ncan't catch SIGINT\n"); return -1; } alarm(5); while (!stop) {} return 0; }