[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