Skip to content

Instantly share code, notes, and snippets.

@skyitachi
Created July 29, 2018 14:34
Show Gist options
  • Save skyitachi/f854b8134b62d401c3e778305c34c4fe to your computer and use it in GitHub Desktop.
Save skyitachi/f854b8134b62d401c3e778305c34c4fe to your computer and use it in GitHub Desktop.
timerfd example
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <time.h>
static char *itimerspec_dump(struct itimerspec *ts);
int main()
{
clock_t start, end;
int tfd, epfd, ret;
struct epoll_event ev;
struct itimerspec ts;
int msec = 1000; // timer fires after 10msec
uint64_t res;
printf("testcase start\n");
tfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (tfd == -1) {
printf("timerfd_create() failed: errno=%d\n", errno);
return EXIT_FAILURE;
}
printf("created timerfd %d\n", tfd);
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ts.it_value.tv_sec = msec / 1000;
ts.it_value.tv_nsec = (msec % 1000) * 1000000;
if (timerfd_settime(tfd, 0, &ts, NULL) < 0) {
printf("timerfd_settime() failed: errno=%d\n", errno);
close(tfd);
return EXIT_FAILURE;
}
printf("set timerfd time=%s\n", itimerspec_dump(&ts));
epfd = epoll_create(1);
if (epfd == -1) {
printf("epoll_create() failed: errno=%d\n", errno);
close(tfd);
return EXIT_FAILURE;
}
printf("created epollfd %d\n", epfd);
ev.events = EPOLLIN;
ev.data.fd = tfd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, tfd, &ev) == -1) {
printf("epoll_ctl(ADD) failed: errno=%d\n", errno);
close(epfd);
close(tfd);
return EXIT_FAILURE;
}
printf("added timerfd to epoll set\n");
memset(&ev, 0, sizeof(ev));
time_t ts1, ts2;
time(&ts1);
struct epoll_event events[10];
int found = 0;
for(;;) {
ret = epoll_wait(epfd, events, 1, 2000); // wait up to 500ms for timer
if (ret < 0) {
printf("epoll_wait() failed: errno=%d\n", errno);
close(epfd);
close(tfd);
return EXIT_FAILURE;
} else if (ret > 0) {
for(int i = 0; i < ret; i++) {
if (events[i].data.fd == tfd) {
found = 1;
time(&ts2);
printf("found\n");
printf("time consumes: %ld seconds\n", (long)(ts2) - (long)(ts1));
break;
}
}
if (found) {
break;
}
}
}
if (close(epfd) == -1) {
printf("failed to close epollfd: errno=%d\n", errno);
return EXIT_FAILURE;
}
if (close(tfd) == -1) {
printf("failed to close timerfd: errno=%d\n", errno);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static char *
itimerspec_dump(struct itimerspec *ts)
{
static char buf[1024];
snprintf(buf, sizeof(buf),
"itimer: [ interval=%lu s %lu ns, next expire=%lu s %lu ns ]",
ts->it_interval.tv_sec,
ts->it_interval.tv_nsec,
ts->it_value.tv_sec,
ts->it_value.tv_nsec
);
return (buf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment