/* Run tasks periodically. * * Author: Steffen Vogel * SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include #include // We can choose between two periodic task implementations //#define PERIODIC_TASK_IMPL NANOSLEEP #define TIMERFD 1 #define CLOCK_NANOSLEEP 2 #define NANOSLEEP 3 #define RDTSC 4 #if defined(__MACH__) #define PERIODIC_TASK_IMPL NANOSLEEP #elif defined(__linux__) #define PERIODIC_TASK_IMPL TIMERFD #else #error "Platform not supported" #endif #if PERIODIC_TASK_IMPL == RDTSC #include #endif struct Task { int clock; // CLOCK_{MONOTONIC,REALTIME} #if PERIODIC_TASK_IMPL == RDTSC // We use cycle counts in RDTSC mode uint64_t period; uint64_t next; #else struct timespec period; // The period of periodic invations of this task struct timespec next; // The timer value for the next invocation #endif #if PERIODIC_TASK_IMPL == TIMERFD int fd; // The timerfd_create(2) file descriptior. #elif PERIODIC_TASK_IMPL == RDTSC struct Tsc tsc; // Initialized by tsc_init(). #endif // Create a new task with the given rate. Task(int clock = CLOCK_REALTIME); ~Task(); // Wait until task elapsed // // @retval 0 An error occured. Maybe the task was stopped. // @retval >0 The nummer of runs this task already fired. uint64_t wait(); void setNext(const struct timespec *next); void setTimeout(double to); void setRate(double rate); void stop(); // Returns a poll'able file descriptor which becomes readable when the timer expires. // // Note: currently not supported on all platforms. int getFD() const; };