[ccan] [PATCH 2/2] time: Add functions to use CLOCK_MONOTONIC
David Gibson
david at gibson.dropbear.id.au
Mon Jun 2 22:03:03 EST 2014
When available, add a time_monotonic() function which uses the monotonic
clock insteadm of the realtime clock. This is safer for measuring
intervals. Also include time_since() variants based on the monotonic clock.
Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
ccan/time/test/run-monotonic.c | 25 +++++++++++++++++++++++++
ccan/time/time.c | 10 ++++++++++
ccan/time/time.h | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)
create mode 100644 ccan/time/test/run-monotonic.c
diff --git a/ccan/time/test/run-monotonic.c b/ccan/time/test/run-monotonic.c
new file mode 100644
index 0000000..4a0d1d7
--- /dev/null
+++ b/ccan/time/test/run-monotonic.c
@@ -0,0 +1,25 @@
+#include <ccan/time/time.h>
+#include <ccan/time/time.c>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+#ifdef TIME_HAVE_MONOTONIC
+ struct timespec t1, t2, t3;
+
+ plan_tests(3);
+
+ /* Test time_now */
+ t1 = time_monotonic();
+ t2 = time_monotonic();
+
+ ok1(!time_less(t2, t1));
+
+ t3.tv_sec = 1;
+ t3.tv_nsec = 0;
+
+ ok1(time_less(time_since_monotonic(t1), t3));
+ ok1(time_since_msec_monotonic(t1) < 1000);
+#endif
+ return exit_status();
+}
diff --git a/ccan/time/time.c b/ccan/time/time.c
index 166832d..f24038b 100644
--- a/ccan/time/time.c
+++ b/ccan/time/time.c
@@ -15,6 +15,7 @@ struct timespec time_now(void)
ret.tv_nsec = now.tv_usec * 1000;
return TIME_CHECK(ret);
}
+
#else
#include <time.h>
struct timespec time_now(void)
@@ -25,6 +26,15 @@ struct timespec time_now(void)
}
#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT */
+#ifdef TIME_HAVE_MONOTONIC
+struct timespec time_monotonic(void)
+{
+ struct timespec ret;
+ clock_gettime(CLOCK_MONOTONIC, &ret);
+ return TIME_CHECK(ret);
+}
+#endif /* TIME_HAVE_MONOTONIC */
+
struct timespec time_divide(struct timespec t, unsigned long div)
{
struct timespec res;
diff --git a/ccan/time/time.h b/ccan/time/time.h
index dc1a0c3..d33f0b0 100644
--- a/ccan/time/time.h
+++ b/ccan/time/time.h
@@ -429,4 +429,44 @@ static inline uint64_t time_since_msec(struct timespec start)
return time_to_msec(time_since(start));
}
+#if HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT
+
+#include <time.h>
+
+#if defined(CLOCK_MONOTONIC)
+#define TIME_HAVE_MONOTONIC 1
+
+/**
+ * time_monotonic - return the current monotonic time
+ *
+ * The monotonic time is measured from some arbitrary point (not the
+ * usual epoch), but it isn't affected by distcontinuous changes in
+ * the system time, making it suitable for interval measurements.
+ */
+struct timespec time_monotonic(void);
+
+/**
+ * time_since_monotonic - monotonic time since another timespec
+ * @start: (monotonic) time to measure from
+ */
+static inline struct timespec time_since_monotonic(struct timespec start)
+{
+ return time_sub(time_monotonic(), start);
+}
+
+/**
+ * time_since_msec_monotonic - number of milliseconds of monotonic
+ * time since an earlier timespec
+ * @start: (monotonic) time to measure from
+ */
+static inline uint64_t time_since_msec_monotonic(struct timespec start)
+{
+ return time_to_msec(time_since_monotonic(start));
+}
+#else
+#error blockits
+#endif /* _POSIX_MONOTONIC_CLOCK */
+#endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT */
+
+
#endif /* CCAN_TIME_H */
--
1.9.3
More information about the ccan
mailing list