diff --git a/include/timing.h b/include/timing.h index 6aafda65e..167cffe78 100644 --- a/include/timing.h +++ b/include/timing.h @@ -16,6 +16,9 @@ #include #include +/** Create a new timer with the given rate. */ +int timerfd_create_rate(double rate); + /** Wait until timer elapsed * * @param fd A file descriptor which was created by timerfd_create(3). diff --git a/lib/file.c b/lib/file.c index 536b6767a..f7df2e7da 100644 --- a/lib/file.c +++ b/lib/file.c @@ -193,22 +193,12 @@ int file_open(struct node *n) serror("Failed to open file for reading: '%s'", f->read.path); /* Create timer */ - f->read_timer = timerfd_create(CLOCK_REALTIME, 0); + f->read_timer = (f->read_rate) + ? timerfd_create_rate(f->read_rate) + : timerfd_create(CLOCK_REALTIME, 0); if (f->read_timer < 0) serror("Failed to create timer"); - /* Arm the timer with a fixed rate */ - if (f->read_rate) { - struct itimerspec its = { - .it_interval = time_from_double(1 / f->read_rate), - .it_value = { 0, 1 }, - }; - - int ret = timerfd_settime(f->read_timer, 0, &its, NULL); - if (ret) - serror("Failed to start timer"); - } - /* Get current time */ struct timespec now = time_now(); @@ -311,7 +301,7 @@ retry: values = msg_fscan(f->read.handle, cur, &flags, NULL); if (!f->read_rate || ftell(f->read.handle) == 0) { struct timespec until = time_add(&MSG_TS(cur), &f->read_offset); - if (timerfd_wait_until(f->read_timer, &until) < 0) + if (timerfd_wait_until(f->read_timer, &until) == 0) serror("Failed to wait for timer"); /* Update timestamp */ @@ -319,7 +309,7 @@ retry: values = msg_fscan(f->read.handle, cur, &flags, NULL); cur->ts.nsec = until.tv_nsec; } else { /* Wait with fixed rate delay */ - if (timerfd_wait(f->read_timer) < 0) + if (timerfd_wait(f->read_timer) == 0) serror("Failed to wait for timer"); /* Update timestamp */ diff --git a/lib/gtfpga.c b/lib/gtfpga.c index 9e4a83b36..db25ddc51 100644 --- a/lib/gtfpga.c +++ b/lib/gtfpga.c @@ -201,17 +201,9 @@ int gtfpga_open(struct node *n) /* Setup timer */ if (g->rate) { - g->fd_irq = timerfd_create(CLOCK_MONOTONIC, 0); + g->fd_irq = timerfd_create_rate(g->rate); if (g->fd_irq < 0) serror("Failed to create timer"); - - struct itimerspec its = { - .it_interval = time_from_double(1 / g->rate), - .it_value = { 0, 1 } - }; - ret = timerfd_settime(g->fd_irq, 0, &its, NULL); - if (ret) - serror("Failed to start timer"); } else /** @todo implement UIO interrupts */ error("UIO irq not implemented yet. Use 'rate' setting"); diff --git a/lib/ngsi.c b/lib/ngsi.c index cf1ce911c..6bc367094 100644 --- a/lib/ngsi.c +++ b/lib/ngsi.c @@ -501,22 +501,12 @@ int ngsi_open(struct node *n) } /* Create timer */ - i->tfd = timerfd_create(CLOCK_MONOTONIC, 0); - if (i->tfd < 0) - serror("Failed to create timer"); - - /* Arm the timer with a fixed rate */ - struct itimerspec its = { - .it_interval = time_from_double(1 / i->rate), - .it_value = { 0, 1 }, - }; - if (i->timeout > 1 / i->rate) warn("Timeout is to large for given rate: %f", i->rate); - ret = timerfd_settime(i->tfd, 0, &its, NULL); - if (ret) - serror("Failed to start timer"); + i->tfd = timerfd_create_rate(i->rate); + if (i->tfd < 0) + serror("Failed to create timer"); i->headers = curl_slist_append(i->headers, "User-Agent: S2SS " VERSION); i->headers = curl_slist_append(i->headers, "Accept: application/json"); @@ -561,7 +551,8 @@ int ngsi_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt struct ngsi *i = n->_vd; int ret; - timerfd_wait(i->tfd); + if (timerfd_wait(i->tfd) == 0) + perror("Failed to wait for timer"); json_t *rentity; json_t *entity = ngsi_build_entity(i, NULL, 0, 0, 0, 0); diff --git a/lib/path.c b/lib/path.c index d2f2b5928..7468800d4 100644 --- a/lib/path.c +++ b/lib/path.c @@ -6,7 +6,6 @@ * Unauthorized copying of this file, via any medium is strictly prohibited. *********************************************************************************/ -#include #include #include @@ -58,7 +57,9 @@ static void * path_run_async(void *arg) for (;;) { /* Check for overruns */ uint64_t expir = timerfd_wait(p->tfd); - if (expir > 1) { + if (expir == 0) + perror("Failed to wait for timer"); + else if (expir > 1) { p->overrun += expir; warn("Overrun detected for path: overruns=%" PRIu64, expir); } @@ -146,18 +147,10 @@ int path_start(struct path *p) /* At fixed rate mode, we start another thread for sending */ if (p->rate) { - struct itimerspec its = { - .it_interval = time_from_double(1 / p->rate), - .it_value = { 0, 1 } - }; - - p->tfd = timerfd_create(CLOCK_REALTIME, 0); + p->tfd = timerfd_create_rate(p->rate); if (p->tfd < 0) serror("Failed to create timer"); - if (timerfd_settime(p->tfd, 0, &its, NULL)) - serror("Failed to start timer"); - pthread_create(&p->sent_tid, NULL, &path_run_async, p); } diff --git a/lib/timing.c b/lib/timing.c index 095ddf446..1c5963cc3 100644 --- a/lib/timing.c +++ b/lib/timing.c @@ -11,6 +11,25 @@ #include "timing.h" +int timerfd_create_rate(double rate) +{ + int fd, ret; + struct itimerspec its = { + .it_interval = time_from_double(1 / rate), + .it_value = { 0, 1 } + }; + + fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd < 0) + return fd; + + ret = timerfd_settime(fd, 0, &its, NULL); + if (ret) + return ret; + + return fd; +} + uint64_t timerfd_wait(int fd) { uint64_t runs; @@ -20,15 +39,17 @@ uint64_t timerfd_wait(int fd) uint64_t timerfd_wait_until(int fd, struct timespec *until) { + int ret; struct itimerspec its = { .it_value = *until, .it_interval = { 0, 0 } }; - if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, NULL)) + ret = timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, NULL); + if (ret) return 0; - else - return timerfd_wait(fd); + + return timerfd_wait(fd); } struct timespec time_now() diff --git a/src/signal.c b/src/signal.c index 7718be5b0..0f4b0b174 100644 --- a/src/signal.c +++ b/src/signal.c @@ -64,18 +64,10 @@ int main(int argc, char *argv[]) type = TYPE_MIXED; /* Setup timer */ - struct itimerspec its = { - .it_interval = time_from_double(1 / rate), - .it_value = { 0, 1 } - }; - - int tfd = timerfd_create(CLOCK_REALTIME, 0); + int tfd = timerfd_create_rate(rate); if (tfd < 0) serror("Failed to create timer"); - if (timerfd_settime(tfd, 0, &its, NULL)) - serror("Failed to start timer"); - /* Print header */ fprintf(stderr, "# %-20s\t\t%s\n", "sec.nsec(seq)", "data[]");