Created
November 21, 2025 19:26
-
-
Save MarekKnapek/184bc92f28a4ac9cc5e4d0c4bd3fe738 to your computer and use it in GitHub Desktop.
Timer code reaction on Daniel Hirsch YouTube video.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stddef.h> /* NULL */ | |
| #include <stdio.h> /* printf fflush */ | |
| #include <stdlib.h> /* abort */ | |
| #include <errno.h> /* errno EINTR */ | |
| #include <poll.h> /* pollfd poll */ | |
| #include <sys/timerfd.h> /* timerfd_create CLOCK_MONOTONIC timerfd_settime */ | |
| #include <time.h> /* itimerspec timespec */ | |
| #include <unistd.h> /* close */ | |
| static int g_timer; | |
| static int g_counter; | |
| static void create_timer(void) | |
| { | |
| int timer; | |
| printf("Creating timer. "); fflush(NULL); | |
| timer = timerfd_create(CLOCK_MONOTONIC, 0); | |
| if(timer == -1) | |
| { | |
| printf("Failed to create timer, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| else | |
| { | |
| g_timer = timer; | |
| printf("Timer created, fd: %d.\n", timer); fflush(NULL); | |
| } | |
| } | |
| static void destroy_timer(void) | |
| { | |
| int err; | |
| printf("Closing timer. "); fflush(NULL); | |
| err = close(g_timer); | |
| if(err != 0) | |
| { | |
| printf("Error closing timer, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| printf("Timer closed.\n"); fflush(NULL); | |
| } | |
| static void schedule_timer(void) | |
| { | |
| struct itimerspec new_val; | |
| int err; | |
| printf("Scheduling timer. "); fflush(NULL); | |
| new_val.it_interval.tv_sec = 0; | |
| new_val.it_interval.tv_nsec = 0; | |
| new_val.it_value.tv_sec = 1; | |
| new_val.it_value.tv_nsec = 0; | |
| err = timerfd_settime(g_timer, 0, &new_val, NULL); | |
| if(err != 0) | |
| { | |
| printf("Failed to schedule timer, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| printf("Timer scheduled.\n"); fflush(NULL); | |
| } | |
| static void some_other_work(void) | |
| { | |
| struct timespec dur; | |
| struct timespec rem; | |
| int err; | |
| printf("Doing some other work. "); fflush(NULL); | |
| dur.tv_sec = 0; | |
| dur.tv_nsec = 333 * 1000 * 1000; | |
| for(;;) | |
| { | |
| err = nanosleep(&dur, &rem); | |
| if(err == 0) | |
| { | |
| printf("Some other work done.\n"); fflush(NULL); | |
| break; | |
| } | |
| else if(err == -1 && errno == EINTR) | |
| { | |
| printf("Work interrupted by signal, continuing to work.\n"); fflush(NULL); | |
| dur = rem; | |
| } | |
| else | |
| { | |
| printf("Failed to do some other work, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| } | |
| } | |
| static void wait_for_timer(void) | |
| { | |
| struct pollfd fds; | |
| int err; | |
| printf("Waiting for timer.\n"); fflush(NULL); | |
| for(;;) | |
| { | |
| fds.fd = g_timer; | |
| fds.events = POLLIN; | |
| fds.revents = 0; | |
| err = poll(&fds, 1, 0); /* timeout could be specified here, so you don't burn 100% of CPU */ | |
| if(err == -1) | |
| { | |
| printf("Error polling for timer, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| else if(err == 0) | |
| { | |
| printf("Timer not ready yet.\n"); fflush(NULL); | |
| some_other_work(); | |
| } | |
| else if(err == 1) | |
| { | |
| printf("Timer expired.\n"); fflush(NULL); | |
| ++g_counter; | |
| if(g_counter == 3) | |
| { | |
| break; | |
| } | |
| schedule_timer(); | |
| } | |
| else | |
| { | |
| printf("Other error polling for timer, aborting.\n"); fflush(NULL); | |
| abort(); | |
| } | |
| } | |
| printf("Done waiting.\n"); fflush(NULL); | |
| } | |
| int main(void) | |
| { | |
| printf("The program started.\n"); fflush(NULL); | |
| create_timer(); | |
| schedule_timer(); | |
| wait_for_timer(); | |
| destroy_timer(); | |
| printf("The program is exiting.\n"); fflush(NULL); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment