int main(int argc, char *argv[]) { struct itimerspec ts; struct timespec start, now; int maxExp, fd, secs, nanosecs; uint64_t numExp, totalExp; ssize_t s; if (argc < 2 || strcmp(argv[1], "--help") == 0) usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]] [max-exp]\n", argv[0]); itimerspecFromStr(argv[1], &ts); maxExp = (argc > 2) ? getInt(argv[2], GN_GT_0, "max-exp") : 1; fd = timerfd_create(CLOCK_REALTIME, 0); if (fd == -1) errExit("timerfd_create"); if (timerfd_settime(fd, 0, &ts, NULL) == -1) errExit("timerfd_settime"); if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) errExit("clock_gettime"); for (totalExp = 0; totalExp < maxExp;) { /* Read number of expirations on the timer, and then display time elapsed since timer was started, followed by number of expirations read and total expirations so far. */ s = read(fd, &numExp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) errExit("read"); totalExp += numExp; if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) errExit("clock_gettime"); secs = now.tv_sec - start.tv_sec; nanosecs = now.tv_nsec - start.tv_nsec; if (nanosecs < 0) { secs--; nanosecs += 1000000000; } printf("%d.%03d: expirations read: %llu; total=%llu\n", secs, (nanosecs + 500000) / 1000000, (unsigned long long) numExp, (unsigned long long) totalExp); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct sigevent sev; struct itimerspec ts; timer_t *tidlist; int s, j; if (argc < 2) usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]]...\n", argv[0]); tidlist = calloc(argc - 1, sizeof(timer_t)); if (tidlist == NULL) errExit("malloc"); sev.sigev_notify = SIGEV_THREAD; /* Notify via thread */ sev.sigev_notify_function = threadFunc; /* Thread start function */ sev.sigev_notify_attributes = NULL; /* Could be pointer to pthread_attr_t structure */ /* Create and start one timer for each command-line argument */ for (j = 0; j < argc - 1; j++) { itimerspecFromStr(argv[j + 1], &ts); sev.sigev_value.sival_ptr = &tidlist[j]; /* Passed as argument to threadFunc() */ if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1) errExit("timer_create"); printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]); if (timer_settime(tidlist[j], 0, &ts, NULL) == -1) errExit("timer_settime"); } /* The main thread waits on a condition variable that is signaled on each invocation of the thread notification function. We print a message so that the user can see that this occurred. */ s = pthread_mutex_lock(&mtx); if (s != 0) errExitEN(s, "pthread_mutex_lock"); for (;;) { s = pthread_cond_wait(&cond, &mtx); if (s != 0) errExitEN(s, "pthread_cond_wait"); printf("main(): expireCnt = %d\n", expireCnt); } }
int main(int argc, char *argv[]) { struct itimerspec ts; struct sigaction sa; struct sigevent sev; timer_t *tidlist; int j; if (argc < 2) usageErr("%s secs[/nsecs][:int-secs[/int-nsecs]]...\n", argv[0]); tidlist = calloc(argc - 1, sizeof(timer_t)); if (tidlist == NULL) errExit("malloc"); /* Establish handler for notification signal */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handler; sigemptyset(&sa.sa_mask); if (sigaction(TIMER_SIG, &sa, NULL) == -1) errExit("sigaction"); /* Create and start one timer for each command-line argument */ sev.sigev_notify = SIGEV_SIGNAL; /* Notify via signal */ sev.sigev_signo = TIMER_SIG; /* Notify using this signal */ for (j = 0; j < argc - 1; j++) { itimerspecFromStr(argv[j + 1], &ts); sev.sigev_value.sival_ptr = &tidlist[j]; /* Allows handler to get ID of this timer */ if (timer_create(CLOCK_REALTIME, &sev, &tidlist[j]) == -1) errExit("timer_create"); printf("Timer ID: %ld (%s)\n", (long) tidlist[j], argv[j + 1]); if (timer_settime(tidlist[j], 0, &ts, NULL) == -1) errExit("timer_settime"); } for (;;) /* Wait for incoming timer signals */ pause(); }