From c40a515eee8a8e361f69b2bf5f3f59362413d196 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 21 Sep 2014 10:02:54 +0100 Subject: [PATCH] Add a general purpose timer for different time granularities (seconds, milliseconds, microseconds and nanoseconds). --- include/Makefile.am | 1 + include/tr/timer.h | 57 ++++++++++++++++++++++++++++++++++++ include/trbase.h | 1 + src/Makefile.am | 3 ++ src/timer.c | 44 ++++++++++++++++++++++++++++ src/timer_get.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ src/timer_set.c | 38 ++++++++++++++++++++++++ 7 files changed, 214 insertions(+) create mode 100644 include/tr/timer.h create mode 100644 src/timer.c create mode 100644 src/timer_get.c create mode 100644 src/timer_set.c diff --git a/include/Makefile.am b/include/Makefile.am index 18e94b7..491447d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -4,6 +4,7 @@ nobase_include_HEADERS = trbase.h \ tr/interface.h \ tr/memory.h \ tr/logger.h \ + tr/timer.h \ tr/print_trace.h \ tr/sized_data.h \ tr/tree_macros.h \ diff --git a/include/tr/timer.h b/include/tr/timer.h new file mode 100644 index 0000000..4a9a882 --- /dev/null +++ b/include/tr/timer.h @@ -0,0 +1,57 @@ +/** + * \file + * A timer with second, millisec, microsec or nanosec granularity. + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TR_TIMER_H__ +#define __TR_TIMER_H__ + +#include "trbase.h" + +typedef enum { + TR_TBASE_NAN = 0, + TR_TBASE_MIC, + TR_TBASE_MIL, + TR_TBASE_SEC +} TR_eTimeoutBase; + +TR_CLASS(TR_Timer) { + int sec; + int nsec; + TR_eTimeoutBase base; + unsigned long timeout; +}; + +TR_INSTANCE_INIT(TR_Timer); +TR_CLASSVARS_DECL(TR_Timer) {}; + +void TR_timerSet(TR_Timer, TR_eTimeoutBase, unsigned long); +unsigned long TR_timerGet(TR_Timer, unsigned long *); // 2nd arg gets amount of + // missed since last check. + +#define TR_timerSetNan(timer, val) (TR_timerSet((timer), TR_TBASE_NAN, (val))) +#define TR_timerSetMic(timer, val) (TR_timerSet((timer), TR_TBASE_MIC, (val))) +#define TR_timerSetMil(timer, val) (TR_timerSet((timer), TR_TBASE_MIL, (val))) +#define TR_timerSetSec(timer, val) (TR_timerSet((timer), TR_TBASE_SEC, (val))) + +#endif // __TR_TIMER_H__ + +// vim: set ts=4 sw=4: diff --git a/include/trbase.h b/include/trbase.h index 09e900d..72ab59d 100644 --- a/include/trbase.h +++ b/include/trbase.h @@ -5,6 +5,7 @@ #include "tr/memory.h" #include "tr/class.h" #include "tr/logger.h" +#include "tr/timer.h" #include "tr/print_trace.h" #include "tr/sized_data.h" #include "tr/interface.h" diff --git a/src/Makefile.am b/src/Makefile.am index e7a9081..bd42cac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,9 @@ AM_CFLAGS += -I../include/ TR_CLASS = memory.c \ interface.c \ logger.c \ + timer.c \ + timer_set.c \ + timer_get.c \ print_trace.c \ stderr.c \ syslog.c \ diff --git a/src/timer.c b/src/timer.c new file mode 100644 index 0000000..3038e59 --- /dev/null +++ b/src/timer.c @@ -0,0 +1,44 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "trbase.h" + +static +int +timerCtor(void * _this, va_list * params) +{ + TR_eTimeoutBase base = va_arg(*params, TR_eTimeoutBase); + unsigned long timeout = va_arg(*params, unsigned long); + + TR_timerSet((TR_Timer)_this, base, timeout); + + return 0; +} + +static void timerDtor(void * _this) {} + +TR_INIT_IFACE(TR_Class, timerCtor, timerDtor, NULL); +TR_CREATE_CLASS(TR_Timer, NULL, NULL, TR_IF(TR_Class)); + +// vim: set ts=4 sw=4: diff --git a/src/timer_get.c b/src/timer_get.c new file mode 100644 index 0000000..ae39ce5 --- /dev/null +++ b/src/timer_get.c @@ -0,0 +1,70 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "trbase.h" + +unsigned long +TR_timerGet(TR_Timer this, unsigned long * missed) +{ + struct timespec now; + unsigned long long elapsed; + unsigned long sec_factor; + long nan_factor; + unsigned long _missed; + + clock_gettime(CLOCK_REALTIME, &now); + + switch (this->base) { + case TR_TBASE_NAN: + sec_factor = 1000 * 1000 * 1000; + break; + case TR_TBASE_MIC: + sec_factor = 1000 * 1000; + break; + case TR_TBASE_MIL: + sec_factor = 1000; + break; + case TR_TBASE_SEC: + sec_factor = 1; + break; + } + + nan_factor = 1000 * 1000 * 1000 / sec_factor; + elapsed = (now.tv_sec - this->sec) * sec_factor + + (now.tv_nsec - this->nsec) / nan_factor; + + _missed = elapsed / this->timeout; + if (_missed) { + this->sec += _missed * this->timeout * sec_factor / nan_factor; + this->nsec += _missed * this->timeout * sec_factor % nan_factor; + *missed = _missed; + } else { + *missed = 0; + } + + return this->timeout - (elapsed % this->timeout); +} + +// vim: set ts=4 sw=4: diff --git a/src/timer_set.c b/src/timer_set.c new file mode 100644 index 0000000..2bd3e25 --- /dev/null +++ b/src/timer_set.c @@ -0,0 +1,38 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2014 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "trbase.h" + +void +TR_timerSet(TR_Timer this, TR_eTimeoutBase base, unsigned long timeout) +{ + struct timespec set; + clock_gettime(CLOCK_REALTIME, &set); + this->sec = set.tv_sec; + this->nsec = set.tv_nsec; + this->base = base; + this->timeout = timeout; +} + +// vim: set ts=4 sw=4: