Skip to content

Instantly share code, notes, and snippets.

@MarekKnapek
Created November 21, 2025 19:26
Show Gist options
  • Select an option

  • Save MarekKnapek/184bc92f28a4ac9cc5e4d0c4bd3fe738 to your computer and use it in GitHub Desktop.

Select an option

Save MarekKnapek/184bc92f28a4ac9cc5e4d0c4bd3fe738 to your computer and use it in GitHub Desktop.
Timer code reaction on Daniel Hirsch YouTube video.
#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