#include #include #include #include #include #include #include #include static int do_print; static int do_quit; static size_t loops; void sig_handler(int signum) { printf("ok"); switch (signum) { case SIGQUIT: case SIGTERM: case SIGINT: signal(SIGINT, SIG_DFL); do_quit = 1; __attribute__((fallthrough)); case SIGUSR1: do_print = 1; break; case SIGHUP: loops = 0; default: break; } } int deadline(size_t period_ms) { #ifndef EDF int tfd = -1; struct itimerspec itval; int rc = 0; tfd = timerfd_create(CLOCK_MONOTONIC, 0); if (tfd == -1) err(-1, "timerfd"); itval.it_interval.tv_sec = 0; itval.it_interval.tv_nsec = period_ms * 1000 * 1000; itval.it_value.tv_sec = 0; itval.it_value.tv_nsec = itval.it_interval.tv_nsec; rc = timerfd_settime(tfd, 0, &itval, NULL); if (rc) err(-1, "timerfd_settime"); do { static unsigned long long overrun; rc = read(tfd, &overrun, sizeof overrun); if (rc == -1) { err(-1, "Timer read"); } ++loops; if (do_print) { do_print = 0; fprintf(stdout, "Loops: %zu.\n", loops); } } while(!do_quit); #endif } int main(int argc, char *argv[]) { int rc; struct sigaction sa = {0}; /* Set up the structure to specify the new action. */ sigemptyset (&sa.sa_mask); sigaddset(&sa.sa_mask, SIGINT); sa.sa_handler = &sig_handler; sa.sa_flags = 0; sigaddset(&sa.sa_mask, SIGTERM); sigaddset(&sa.sa_mask, SIGINT); sigaddset(&sa.sa_mask, SIGHUP); sigaddset(&sa.sa_mask, SIGUSR1); sigaddset(&sa.sa_mask, SIGQUIT); if (sigaction (SIGINT, &sa, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } sigaction (SIGTERM, &sa, NULL); sigaction (SIGQUIT, &sa, NULL); sigaction (SIGUSR1, &sa, NULL); sigaction (SIGHUP, &sa, NULL); printf("[%d] Starting deadline thread.\n", getpid()); rc = deadline(500); exit(rc ? EXIT_FAILURE : EXIT_SUCCESS); }