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: