From e7cbdf694e58c546677d2bf15500db5c09c7b492 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 5 Sep 2017 16:41:05 +0200 Subject: [PATCH] task: add task_set_rate() --- include/villas/task.h | 4 +++- lib/task.c | 45 +++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/include/villas/task.h b/include/villas/task.h index 71d1b3a1c..6f67916f8 100644 --- a/include/villas/task.h +++ b/include/villas/task.h @@ -64,10 +64,12 @@ int task_destroy(struct task *t); */ uint64_t task_wait_until_next_period(struct task *t); +int task_set_rate(struct task *t, double rate); + /** Wait until a fixed time in the future is reached * * @param until A pointer to a time in the future. */ int task_wait_until(struct task *t, const struct timespec *until); -int task_fd(struct task *t); \ No newline at end of file +int task_fd(struct task *t); diff --git a/lib/task.c b/lib/task.c index bf2dcf20b..04035d897 100644 --- a/lib/task.c +++ b/lib/task.c @@ -35,32 +35,43 @@ int task_init(struct task *t, double rate, int clock) { + int ret; + t->clock = clock; + +#if PERIODIC_TASK_IMPL == TIMERFD + t->fd = timerfd_create(t->clock, 0); + if (t->fd < 0) + return -1; +#endif + + ret = task_set_rate(t, rate); + if (ret) + return ret; + + return 0; +} + +int task_set_rate(struct task *t, double rate) +{ t->period = rate ? time_from_double(1.0 / rate) : (struct timespec) { 0, 0 }; #if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP struct timespec now; - + clock_gettime(t->clock, &now); t->next_period = time_add(&now, &t->period); #elif PERIODIC_TASK_IMPL == TIMERFD int ret; - struct itimerspec its = { .it_interval = t->period, .it_value = t->period }; - t->fd = timerfd_create(t->clock, 0); - if (t->fd < 0) - return -1; - ret = timerfd_settime(t->fd, 0, &its, NULL); if (ret) return ret; -#else - #error "Invalid period task implementation" #endif return 0; @@ -71,7 +82,7 @@ int task_destroy(struct task *t) #if PERIODIC_TASK_IMPL == TIMERFD return close(t->fd); #endif - + return 0; } @@ -82,7 +93,7 @@ static int time_lt(const struct timespec *lhs, const struct timespec *rhs) return lhs->tv_nsec < rhs->tv_nsec; else return lhs->tv_sec < rhs->tv_sec; - + return 0; } #endif @@ -94,13 +105,13 @@ uint64_t task_wait_until_next_period(struct task *t) #if PERIODIC_TASK_IMPL == CLOCK_NANOSLEEP || PERIODIC_TASK_IMPL == NANOSLEEP ret = task_wait_until(t, &t->next_period); - + struct timespec now; - + ret = clock_gettime(t->clock, &now); if (ret) return 0; - + for (runs = 0; time_lt(&t->next_period, &now); runs++) t->next_period = time_add(&t->next_period, &t->period); @@ -111,7 +122,7 @@ uint64_t task_wait_until_next_period(struct task *t) #else #error "Invalid period task implementation" #endif - + return runs; } @@ -135,7 +146,7 @@ retry: ret = clock_nanosleep(t->clock, TIMER_ABSTIME, until, NULL); ret = nanosleep(&delta, NULL); #elif PERIODIC_TASK_IMPL == TIMERFD uint64_t runs; - + struct itimerspec its = { .it_value = *until, .it_interval = { 0, 0 } @@ -151,7 +162,7 @@ retry: ret = clock_nanosleep(t->clock, TIMER_ABSTIME, until, NULL); #else #error "Invalid period task implementation" #endif - + return 0; } @@ -162,4 +173,4 @@ int task_fd(struct task *t) #else return -1; #endif -} \ No newline at end of file +}