#include #include #include #include #include struct periodic_task { struct timespec r; int period; }; #define NSEC_PER_SEC 1000000000ULL static inline void timespec_add_us(struct timespec *t, uint64_t d) { d *= 1000; d += t->tv_nsec; while (d >= NSEC_PER_SEC) { d -= NSEC_PER_SEC; t->tv_sec += 1; } t->tv_nsec = d; } static void wait_next_activation(struct periodic_task *t) { clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &t->r, NULL); timespec_add_us(&t->r, t->period); } struct periodic_task *start_periodic_timer(uint64_t offs, int t) { struct periodic_task *p; p = malloc(sizeof(struct periodic_task)); if (p == NULL) { return NULL; } clock_gettime(CLOCK_REALTIME, &p->r); timespec_add_us(&p->r, offs); p->period = t; return p; } static void job_body(void) { static int cnt; static uint64_t start; uint64_t t; struct timeval tv; if (start == 0) { gettimeofday(&tv, NULL); start = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; } gettimeofday(&tv, NULL); t = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; if (cnt && (cnt % 100) == 0) { printf("Avg time: %f\n", (double)(t - start) / (double)cnt); } cnt++; } int main(int argc, char *argv[]) { struct periodic_task *t; t = start_periodic_timer(2000000, 5000); if (t == NULL) { perror("Start Periodic Timer"); return -1; } while(1) { wait_next_activation(t); job_body(); } return 0; }