From c0047d701aa88161bc2c7e5aced8c9c63239ccbf Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 29 Aug 2012 17:54:16 +0200 Subject: [PATCH] misc: add timer infrastructure Timers can be used to measure time-delays with microsecond resolution. This is heavily used for performance-tests and to improve rendering performance. Signed-off-by: David Herrmann --- src/static_misc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ src/static_misc.h | 15 +++++++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/static_misc.c b/src/static_misc.c index 152d06b..93fe42c 100644 --- a/src/static_misc.c +++ b/src/static_misc.c @@ -32,8 +32,10 @@ #include #include +#include #include #include +#include #include "htable.h" #include "static_misc.h" @@ -517,3 +519,94 @@ size_t kmscon_array_get_element_size(struct kmscon_array *arr) return arr->element_size; } + +struct kmscon_timer { + struct timespec start; + uint64_t elapsed; +}; + +int kmscon_timer_new(struct kmscon_timer **out) +{ + struct kmscon_timer *timer; + + if (!out) + return -EINVAL; + + timer = malloc(sizeof(*timer)); + if (!timer) + return -ENOMEM; + memset(timer, 0, sizeof(*timer)); + kmscon_timer_reset(timer); + + *out = timer; + return 0; +} + +void kmscon_timer_free(struct kmscon_timer *timer) +{ + if (!timer) + return; + + free(timer); +} + +void kmscon_timer_reset(struct kmscon_timer *timer) +{ + if (!timer) + return; + + clock_gettime(CLOCK_MONOTONIC, &timer->start); + timer->elapsed = 0; +} + +void kmscon_timer_start(struct kmscon_timer *timer) +{ + if (!timer) + return; + + clock_gettime(CLOCK_MONOTONIC, &timer->start); +} + +uint64_t kmscon_timer_stop(struct kmscon_timer *timer) +{ + struct timespec spec; + int64_t off, nsec; + + if (!timer) + return 0; + + clock_gettime(CLOCK_MONOTONIC, &spec); + off = spec.tv_sec - timer->start.tv_sec; + nsec = spec.tv_nsec - timer->start.tv_nsec; + if (nsec < 0) { + --off; + nsec += 1000000000ULL; + } + off *= 1000000; + off += nsec / 1000; + + memcpy(&timer->start, &spec, sizeof(spec)); + timer->elapsed += off; + return timer->elapsed; +} + +uint64_t kmscon_timer_elapsed(struct kmscon_timer *timer) +{ + struct timespec spec; + int64_t off, nsec; + + if (!timer) + return 0; + + clock_gettime(CLOCK_MONOTONIC, &spec); + off = spec.tv_sec - timer->start.tv_sec; + nsec = spec.tv_nsec - timer->start.tv_nsec; + if (nsec < 0) { + --off; + nsec += 1000000000ULL; + } + off *= 1000000; + off += nsec / 1000; + + return timer->elapsed + off; +} diff --git a/src/static_misc.h b/src/static_misc.h index dc26927..0082f04 100644 --- a/src/static_misc.h +++ b/src/static_misc.h @@ -33,8 +33,9 @@ #define KMSCON_MISC_H #include -#include #include +#include +#include /* miscellaneous */ @@ -110,6 +111,18 @@ size_t kmscon_array_get_element_size(struct kmscon_array *arr); #define KMSCON_ARRAY_AT(_arr, _type, _pos) \ (&((_type*)kmscon_array_get_array(_arr))[(_pos)]) +/* time measurement */ + +struct kmscon_timer; + +int kmscon_timer_new(struct kmscon_timer **out); +void kmscon_timer_free(struct kmscon_timer *timer); + +void kmscon_timer_reset(struct kmscon_timer *timer); +void kmscon_timer_start(struct kmscon_timer *timer); +uint64_t kmscon_timer_stop(struct kmscon_timer *timer); +uint64_t kmscon_timer_elapsed(struct kmscon_timer *timer); + /* double linked list */ struct kmscon_dlist {