Browse Source

time: time_mono() helpers.

From patch by David Gibson, rewritten on new ccan/time.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 11 years ago
parent
commit
95ff213952
3 changed files with 83 additions and 0 deletions
  1. 24 0
      ccan/time/test/run-monotonic.c
  2. 11 0
      ccan/time/time.c
  3. 48 0
      ccan/time/time.h

+ 24 - 0
ccan/time/test/run-monotonic.c

@@ -0,0 +1,24 @@
+#include <ccan/time/time.h>
+#include <ccan/time/time.c>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+	struct timemono t1, t2;
+	struct timerel t3;
+
+	plan_tests(2);
+
+	/* Test time_mono */
+	t1 = time_mono();
+	t2 = time_mono();
+
+	ok1(!time_less_(t2.ts, t1.ts));
+
+	t3.ts.tv_sec = 1;
+	t3.ts.tv_nsec = 0;
+
+	ok1(time_less(timemono_between(t1, t2), t3));
+
+	return exit_status();
+}

+ 11 - 0
ccan/time/time.c

@@ -25,6 +25,17 @@ struct timeabs time_now(void)
 }
 #endif /* HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT */
 
+struct timemono time_mono(void)
+{
+	struct timemono ret;
+#ifdef TIME_HAVE_MONOTONIC
+	clock_gettime(CLOCK_MONOTONIC, &ret.ts);
+#else /* Best we can do */
+	ret.ts = time_now().ts;
+#endif /* !HAVE_TIME_MONOTONIC */
+	return ret;
+}
+
 struct timerel time_divide(struct timerel t, unsigned long div)
 {
 	struct timerel res;

+ 48 - 0
ccan/time/time.h

@@ -48,6 +48,28 @@ struct timeabs {
 	struct timespec ts;
 };
 
+/**
+ * struct timemono - a monotonic time.
+ * @ts: the actual timespec value.
+ *
+ * This comes from the monotonic clock (if available), so it's useful
+ * for measuring intervals as it won't change even if the system clock
+ * is moved for some reason.
+ */
+struct timemono {
+	struct timespec ts;
+};
+
+/**
+ * TIME_HAVE_MONOTONIC - defined if we really have a monotonic clock.
+ *
+ * Otherwise time_mono() just refers to time_now().  Your code might
+ * test this if you really need a monotonic clock.
+ */
+#if (HAVE_CLOCK_GETTIME || HAVE_CLOCK_GETTIME_IN_LIBRT) && defined(CLOCK_MONOTONIC)
+#define TIME_HAVE_MONOTONIC 1
+#endif
+
 struct timespec time_check_(struct timespec in, const char *abortstr);
 
 /**
@@ -99,6 +121,16 @@ struct timeabs timeabs_check(struct timeabs in, const char *abortstr);
  */
 struct timeabs time_now(void);
 
+/**
+ * time_mono - return the current monotonic time
+ *
+ * This value is only really useful for measuring time intervals.
+ *
+ * See also:
+ *	time_since()
+ */
+struct timemono time_mono(void);
+
 static inline bool time_greater_(struct timespec a, struct timespec b)
 {
 	if (TIME_CHECK(a).tv_sec > TIME_CHECK(b).tv_sec)
@@ -272,6 +304,22 @@ static inline struct timerel time_between(struct timeabs recent, struct timeabs
 	return t;
 }
 
+/**
+ * timemono_between - time between two monotonic times
+ * @recent: the larger time.
+ * @old: the smaller time.
+ *
+ * This returns a well formed struct timerel of @recent - @old.
+ */
+static inline struct timerel timemono_between(struct timemono recent,
+					      struct timemono old)
+{
+	struct timerel t;
+
+	t.ts = time_sub_(recent.ts, old.ts);
+	return t;
+}
+
 /**
  * timeabs_sub - subtract a relative time from an absolute time
  * @abs: the absolute time.