[tor-commits] [tor/master] Extract time functionality into lib/wallclock and lib/time

nickm at torproject.org nickm at torproject.org
Thu Jun 28 19:21:00 UTC 2018


commit a097ddb4f5105d33146eb8f6afa7d6cd01d47fea
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jun 28 12:57:01 2018 -0400

    Extract time functionality into lib/wallclock and lib/time
---
 .gitignore                             |   2 +
 Makefile.am                            |   2 +
 src/common/compat.h                    |  43 +--------
 src/common/include.am                  |   2 -
 src/common/util.c                      | 146 -------------------------------
 src/common/util.h                      |   3 -
 src/include.am                         |   1 +
 src/lib/time/.may_include              |   8 ++
 src/{common => lib/time}/compat_time.c |  16 +++-
 src/{common => lib/time}/compat_time.h |   2 +
 src/lib/time/include.am                |  19 ++++
 src/lib/time/tvdiff.c                  | 155 +++++++++++++++++++++++++++++++++
 src/lib/time/tvdiff.h                  |  16 ++++
 src/lib/wallclock/include.am           |   1 +
 src/lib/wallclock/timeval.c            |   0
 src/lib/wallclock/timeval.h            |  58 ++++++++++++
 src/or/circuitstats.c                  |   1 +
 src/or/circuituse.c                    |   1 +
 src/or/geoip.c                         |   1 +
 src/test/test_util.c                   |   1 +
 20 files changed, 281 insertions(+), 197 deletions(-)

diff --git a/.gitignore b/.gitignore
index c940166aa..0b45af3b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -203,6 +203,8 @@ uptime-*.json
 /src/lib/libtor-smartlist-core-testing.a
 /src/lib/libtor-thread.a
 /src/lib/libtor-thread-testing.a
+/src/lib/libtor-time.a
+/src/lib/libtor-time-testing.a
 /src/lib/libtor-tls.a
 /src/lib/libtor-tls-testing.a
 /src/lib/libtor-trace.a
diff --git a/Makefile.am b/Makefile.am
index 5a7271e30..d28eb6149 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ TOR_UTIL_LIBS = \
         src/lib/libtor-thread.a \
         src/lib/libtor-memarea.a \
 	src/lib/libtor-math.a \
+	src/lib/libtor-time.a \
         src/lib/libtor-log.a \
         src/lib/libtor-lock.a \
         src/lib/libtor-fdio.a \
@@ -73,6 +74,7 @@ TOR_UTIL_TESTING_LIBS = \
         src/lib/libtor-thread-testing.a \
         src/lib/libtor-memarea-testing.a \
 	src/lib/libtor-math-testing.a \
+	src/lib/libtor-time-testing.a \
         src/lib/libtor-log-testing.a \
         src/lib/libtor-lock-testing.a \
         src/lib/libtor-fdio-testing.a \
diff --git a/src/common/compat.h b/src/common/compat.h
index 5cd8e7215..582945734 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -59,54 +59,13 @@
 #include "lib/fs/files.h"
 #include "lib/fs/mmap.h"
 #include "lib/fs/userdb.h"
+#include "lib/wallclock/timeval.h"
 
 #include <stdio.h>
 #include <errno.h>
 
 /* ===== Time compatibility */
 
-#ifndef timeradd
-/** Replacement for timeradd on platforms that do not have it: sets tvout to
- * the sum of tv1 and tv2. */
-#define timeradd(tv1,tv2,tvout) \
-  do {                                                  \
-    (tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec;    \
-    (tvout)->tv_usec = (tv1)->tv_usec + (tv2)->tv_usec; \
-    if ((tvout)->tv_usec >= 1000000) {                  \
-      (tvout)->tv_usec -= 1000000;                      \
-      (tvout)->tv_sec++;                                \
-    }                                                   \
-  } while (0)
-#endif /* !defined(timeradd) */
-
-#ifndef timersub
-/** Replacement for timersub on platforms that do not have it: sets tvout to
- * tv1 minus tv2. */
-#define timersub(tv1,tv2,tvout) \
-  do {                                                  \
-    (tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec;    \
-    (tvout)->tv_usec = (tv1)->tv_usec - (tv2)->tv_usec; \
-    if ((tvout)->tv_usec < 0) {                         \
-      (tvout)->tv_usec += 1000000;                      \
-      (tvout)->tv_sec--;                                \
-    }                                                   \
-  } while (0)
-#endif /* !defined(timersub) */
-
-#ifndef timercmp
-/** Replacement for timercmp on platforms that do not have it: returns true
- * iff the relational operator "op" makes the expression tv1 op tv2 true.
- *
- * Note that while this definition should work for all boolean operators, some
- * platforms' native timercmp definitions do not support >=, <=, or ==.  So
- * don't use those.
- */
-#define timercmp(tv1,tv2,op)                    \
-  (((tv1)->tv_sec == (tv2)->tv_sec) ?           \
-   ((tv1)->tv_usec op (tv2)->tv_usec) :         \
-   ((tv1)->tv_sec op (tv2)->tv_sec))
-#endif /* !defined(timercmp) */
-
 /* ===== File compatibility */
 
 /* ===== Net compatibility */
diff --git a/src/common/include.am b/src/common/include.am
index 2d7297665..bb1a3ee42 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -27,7 +27,6 @@ LIBOR_A_SRC = \
   src/common/address_set.c				\
   src/common/buffers.c					\
   src/common/compat.c					\
-  src/common/compat_time.c				\
   src/common/util.c					\
   src/common/token_bucket.c				\
   src/common/workqueue.c				\
@@ -64,7 +63,6 @@ COMMONHEADERS = \
   src/common/buffers.h				\
   src/common/compat.h				\
   src/common/compat_libevent.h			\
-  src/common/compat_time.h			\
   src/common/handles.h				\
   src/common/procmon.h				\
   src/common/timers.h				\
diff --git a/src/common/util.c b/src/common/util.c
index e1fae0dea..b31bb834e 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -135,152 +135,6 @@ ENABLE_GCC_WARNING(aggregate-return)
  * Time
  * ===== */
 
-#define TOR_USEC_PER_SEC 1000000
-
-/** Return the difference between start->tv_sec and end->tv_sec.
- * Returns INT64_MAX on overflow and underflow.
- */
-static int64_t
-tv_secdiff_impl(const struct timeval *start, const struct timeval *end)
-{
-  const int64_t s = (int64_t)start->tv_sec;
-  const int64_t e = (int64_t)end->tv_sec;
-
-  /* This may not be the most efficient way of implemeting this check,
-   * but it's easy to see that it's correct and doesn't overflow */
-
-  if (s > 0 && e < INT64_MIN + s) {
-    /* s is positive: equivalent to e - s < INT64_MIN, but without any
-     * overflow */
-    return INT64_MAX;
-  } else if (s < 0 && e > INT64_MAX + s) {
-    /* s is negative: equivalent to e - s > INT64_MAX, but without any
-     * overflow */
-    return INT64_MAX;
-  }
-
-  return e - s;
-}
-
-/** Return the number of microseconds elapsed between *start and *end.
- * Returns LONG_MAX on overflow and underflow.
- */
-long
-tv_udiff(const struct timeval *start, const struct timeval *end)
-{
-  /* Sanity check tv_usec */
-  if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
-    log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
-             "start tv_usec: " I64_FORMAT " microseconds",
-             I64_PRINTF_ARG(start->tv_usec));
-    return LONG_MAX;
-  }
-
-  if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
-    log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
-             "end tv_usec: " I64_FORMAT " microseconds",
-             I64_PRINTF_ARG(end->tv_usec));
-    return LONG_MAX;
-  }
-
-  /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
-   */
-  int64_t udiff;
-  const int64_t secdiff = tv_secdiff_impl(start, end);
-
-  /* end->tv_usec - start->tv_usec can be up to 1 second either way */
-  if (secdiff > (int64_t)(LONG_MAX/1000000 - 1) ||
-      secdiff < (int64_t)(LONG_MIN/1000000 + 1)) {
-    log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
-             "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
-    return LONG_MAX;
-  }
-
-  /* we'll never get an overflow here, because we check that both usecs are
-   * between 0 and TV_USEC_PER_SEC. */
-  udiff = secdiff*1000000 + ((int64_t)end->tv_usec - (int64_t)start->tv_usec);
-
-  /* Some compilers are smart enough to work out this is a no-op on L64 */
-#if SIZEOF_LONG < 8
-  if (udiff > (int64_t)LONG_MAX || udiff < (int64_t)LONG_MIN) {
-    return LONG_MAX;
-  }
-#endif
-
-  return (long)udiff;
-}
-
-/** Return the number of milliseconds elapsed between *start and *end.
- * If the tv_usec difference is 500, rounds away from zero.
- * Returns LONG_MAX on overflow and underflow.
- */
-long
-tv_mdiff(const struct timeval *start, const struct timeval *end)
-{
-  /* Sanity check tv_usec */
-  if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
-    log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
-             "start tv_usec: " I64_FORMAT " microseconds",
-             I64_PRINTF_ARG(start->tv_usec));
-    return LONG_MAX;
-  }
-
-  if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
-    log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
-             "end tv_usec: " I64_FORMAT " microseconds",
-             I64_PRINTF_ARG(end->tv_usec));
-    return LONG_MAX;
-  }
-
-  /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
-   */
-  int64_t mdiff;
-  const int64_t secdiff = tv_secdiff_impl(start, end);
-
-  /* end->tv_usec - start->tv_usec can be up to 1 second either way, but the
-   * mdiff calculation may add another temporary second for rounding.
-   * Whether this actually causes overflow depends on the compiler's constant
-   * folding and order of operations. */
-  if (secdiff > (int64_t)(LONG_MAX/1000 - 2) ||
-      secdiff < (int64_t)(LONG_MIN/1000 + 1)) {
-    log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
-             "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
-    return LONG_MAX;
-  }
-
-  /* Subtract and round */
-  mdiff = secdiff*1000 +
-      /* We add a million usec here to ensure that the result is positive,
-       * so that the round-towards-zero behavior of the division will give
-       * the right result for rounding to the nearest msec. Later we subtract
-       * 1000 in order to get the correct result.
-       * We'll never get an overflow here, because we check that both usecs are
-       * between 0 and TV_USEC_PER_SEC. */
-      ((int64_t)end->tv_usec - (int64_t)start->tv_usec + 500 + 1000000) / 1000
-      - 1000;
-
-  /* Some compilers are smart enough to work out this is a no-op on L64 */
-#if SIZEOF_LONG < 8
-  if (mdiff > (int64_t)LONG_MAX || mdiff < (int64_t)LONG_MIN) {
-    return LONG_MAX;
-  }
-#endif
-
-  return (long)mdiff;
-}
-
-/**
- * Converts timeval to milliseconds.
- */
-int64_t
-tv_to_msec(const struct timeval *tv)
-{
-  int64_t conv = ((int64_t)tv->tv_sec)*1000L;
-  /* Round ghetto-style */
-  conv += ((int64_t)tv->tv_usec+500)/1000L;
-  return conv;
-}
-
 #ifdef _WIN32
 HANDLE
 load_windows_system_library(const TCHAR *library_name)
diff --git a/src/common/util.h b/src/common/util.h
index 3068f023a..f174cd366 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -66,9 +66,6 @@ void tor_log_mallinfo(int severity);
 /* String manipulation */
 
 /* Time helpers */
-long tv_udiff(const struct timeval *start, const struct timeval *end);
-long tv_mdiff(const struct timeval *start, const struct timeval *end);
-int64_t tv_to_msec(const struct timeval *tv);
 
 /* File helpers */
 
diff --git a/src/include.am b/src/include.am
index 8345813b7..ba5421e09 100644
--- a/src/include.am
+++ b/src/include.am
@@ -24,6 +24,7 @@ include src/lib/string/include.am
 include src/lib/smartlist_core/include.am
 include src/lib/testsupport/include.am
 include src/lib/thread/include.am
+include src/lib/time/include.am
 include src/lib/tls/include.am
 include src/lib/trace/include.am
 include src/lib/wallclock/include.am
diff --git a/src/lib/time/.may_include b/src/lib/time/.may_include
new file mode 100644
index 000000000..a35e7a34e
--- /dev/null
+++ b/src/lib/time/.may_include
@@ -0,0 +1,8 @@
+orconfig.h
+
+lib/cc/*.h
+lib/err/*.h
+lib/intmath/*.h
+lib/log/*.h
+lib/time/*.h
+lib/wallclock/*.h
diff --git a/src/common/compat_time.c b/src/lib/time/compat_time.c
similarity index 99%
rename from src/common/compat_time.c
rename to src/lib/time/compat_time.c
index 148f2f895..f50ccb5e3 100644
--- a/src/common/compat_time.c
+++ b/src/lib/time/compat_time.c
@@ -10,7 +10,12 @@
  **/
 
 #define COMPAT_TIME_PRIVATE
-#include "common/compat.h"
+#include "lib/time/compat_time.h"
+
+#include "lib/err/torerr.h"
+#include "lib/log/torlog.h"
+#include "lib/log/util_bug.h"
+#include "lib/intmath/muldiv.h"
 
 #ifdef _WIN32
 #include <winsock2.h>
@@ -20,6 +25,9 @@
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -34,9 +42,9 @@
 #include <mach/mach_time.h>
 #endif
 
-#include "lib/err/torerr.h"
-#include "lib/log/torlog.h"
-#include "common/util.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 #ifdef _WIN32
 #undef HAVE_CLOCK_GETTIME
diff --git a/src/common/compat_time.h b/src/lib/time/compat_time.h
similarity index 99%
rename from src/common/compat_time.h
rename to src/lib/time/compat_time.h
index 2f7e87a63..4427ce8f9 100644
--- a/src/common/compat_time.h
+++ b/src/lib/time/compat_time.h
@@ -19,6 +19,8 @@
 #define TOR_COMPAT_TIME_H
 
 #include "orconfig.h"
+#include "lib/cc/torint.h"
+
 #include "lib/wallclock/tor_gettimeofday.h"
 
 #ifdef _WIN32
diff --git a/src/lib/time/include.am b/src/lib/time/include.am
new file mode 100644
index 000000000..a3f93a374
--- /dev/null
+++ b/src/lib/time/include.am
@@ -0,0 +1,19 @@
+
+noinst_LIBRARIES += src/lib/libtor-time.a
+
+if UNITTESTS_ENABLED
+noinst_LIBRARIES += src/lib/libtor-time-testing.a
+endif
+
+src_lib_libtor_time_a_SOURCES =	\
+		src/lib/time/compat_time.c	\
+		src/lib/time/tvdiff.c
+
+src_lib_libtor_time_testing_a_SOURCES = \
+	$(src_lib_libtor_time_a_SOURCES)
+src_lib_libtor_time_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
+src_lib_libtor_time_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
+
+noinst_HEADERS +=				\
+		src/lib/time/compat_time.h	\
+		src/lib/time/tvdiff.h
diff --git a/src/lib/time/tvdiff.c b/src/lib/time/tvdiff.c
new file mode 100644
index 000000000..11c881234
--- /dev/null
+++ b/src/lib/time/tvdiff.c
@@ -0,0 +1,155 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "lib/time/tvdiff.h"
+
+#include "lib/cc/compat_compiler.h"
+#include "lib/log/torlog.h"
+
+#define TOR_USEC_PER_SEC 1000000
+
+/** Return the difference between start->tv_sec and end->tv_sec.
+ * Returns INT64_MAX on overflow and underflow.
+ */
+static int64_t
+tv_secdiff_impl(const struct timeval *start, const struct timeval *end)
+{
+  const int64_t s = (int64_t)start->tv_sec;
+  const int64_t e = (int64_t)end->tv_sec;
+
+  /* This may not be the most efficient way of implemeting this check,
+   * but it's easy to see that it's correct and doesn't overflow */
+
+  if (s > 0 && e < INT64_MIN + s) {
+    /* s is positive: equivalent to e - s < INT64_MIN, but without any
+     * overflow */
+    return INT64_MAX;
+  } else if (s < 0 && e > INT64_MAX + s) {
+    /* s is negative: equivalent to e - s > INT64_MAX, but without any
+     * overflow */
+    return INT64_MAX;
+  }
+
+  return e - s;
+}
+
+/** Return the number of microseconds elapsed between *start and *end.
+ * Returns LONG_MAX on overflow and underflow.
+ */
+long
+tv_udiff(const struct timeval *start, const struct timeval *end)
+{
+  /* Sanity check tv_usec */
+  if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
+    log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
+             "start tv_usec: " I64_FORMAT " microseconds",
+             I64_PRINTF_ARG(start->tv_usec));
+    return LONG_MAX;
+  }
+
+  if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
+    log_warn(LD_GENERAL, "comparing times on microsecond detail with bad "
+             "end tv_usec: " I64_FORMAT " microseconds",
+             I64_PRINTF_ARG(end->tv_usec));
+    return LONG_MAX;
+  }
+
+  /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
+   */
+  int64_t udiff;
+  const int64_t secdiff = tv_secdiff_impl(start, end);
+
+  /* end->tv_usec - start->tv_usec can be up to 1 second either way */
+  if (secdiff > (int64_t)(LONG_MAX/1000000 - 1) ||
+      secdiff < (int64_t)(LONG_MIN/1000000 + 1)) {
+    log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
+             "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
+    return LONG_MAX;
+  }
+
+  /* we'll never get an overflow here, because we check that both usecs are
+   * between 0 and TV_USEC_PER_SEC. */
+  udiff = secdiff*1000000 + ((int64_t)end->tv_usec - (int64_t)start->tv_usec);
+
+  /* Some compilers are smart enough to work out this is a no-op on L64 */
+#if SIZEOF_LONG < 8
+  if (udiff > (int64_t)LONG_MAX || udiff < (int64_t)LONG_MIN) {
+    return LONG_MAX;
+  }
+#endif
+
+  return (long)udiff;
+}
+
+/** Return the number of milliseconds elapsed between *start and *end.
+ * If the tv_usec difference is 500, rounds away from zero.
+ * Returns LONG_MAX on overflow and underflow.
+ */
+long
+tv_mdiff(const struct timeval *start, const struct timeval *end)
+{
+  /* Sanity check tv_usec */
+  if (start->tv_usec > TOR_USEC_PER_SEC || start->tv_usec < 0) {
+    log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
+             "start tv_usec: " I64_FORMAT " microseconds",
+             I64_PRINTF_ARG(start->tv_usec));
+    return LONG_MAX;
+  }
+
+  if (end->tv_usec > TOR_USEC_PER_SEC || end->tv_usec < 0) {
+    log_warn(LD_GENERAL, "comparing times on millisecond detail with bad "
+             "end tv_usec: " I64_FORMAT " microseconds",
+             I64_PRINTF_ARG(end->tv_usec));
+    return LONG_MAX;
+  }
+
+  /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
+   */
+  int64_t mdiff;
+  const int64_t secdiff = tv_secdiff_impl(start, end);
+
+  /* end->tv_usec - start->tv_usec can be up to 1 second either way, but the
+   * mdiff calculation may add another temporary second for rounding.
+   * Whether this actually causes overflow depends on the compiler's constant
+   * folding and order of operations. */
+  if (secdiff > (int64_t)(LONG_MAX/1000 - 2) ||
+      secdiff < (int64_t)(LONG_MIN/1000 + 1)) {
+    log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
+             "apart: " I64_FORMAT " seconds", I64_PRINTF_ARG(secdiff));
+    return LONG_MAX;
+  }
+
+  /* Subtract and round */
+  mdiff = secdiff*1000 +
+      /* We add a million usec here to ensure that the result is positive,
+       * so that the round-towards-zero behavior of the division will give
+       * the right result for rounding to the nearest msec. Later we subtract
+       * 1000 in order to get the correct result.
+       * We'll never get an overflow here, because we check that both usecs are
+       * between 0 and TV_USEC_PER_SEC. */
+      ((int64_t)end->tv_usec - (int64_t)start->tv_usec + 500 + 1000000) / 1000
+      - 1000;
+
+  /* Some compilers are smart enough to work out this is a no-op on L64 */
+#if SIZEOF_LONG < 8
+  if (mdiff > (int64_t)LONG_MAX || mdiff < (int64_t)LONG_MIN) {
+    return LONG_MAX;
+  }
+#endif
+
+  return (long)mdiff;
+}
+
+/**
+ * Converts timeval to milliseconds.
+ */
+int64_t
+tv_to_msec(const struct timeval *tv)
+{
+  int64_t conv = ((int64_t)tv->tv_sec)*1000L;
+  /* Round ghetto-style */
+  conv += ((int64_t)tv->tv_usec+500)/1000L;
+  return conv;
+}
diff --git a/src/lib/time/tvdiff.h b/src/lib/time/tvdiff.h
new file mode 100644
index 000000000..215de9cf3
--- /dev/null
+++ b/src/lib/time/tvdiff.h
@@ -0,0 +1,16 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_TVDIFF_H
+#define TOR_TVDIFF_H
+
+#include "lib/cc/torint.h"
+struct timeval;
+
+long tv_udiff(const struct timeval *start, const struct timeval *end);
+long tv_mdiff(const struct timeval *start, const struct timeval *end);
+int64_t tv_to_msec(const struct timeval *tv);
+
+#endif
diff --git a/src/lib/wallclock/include.am b/src/lib/wallclock/include.am
index 7b735e97e..7864c21e1 100644
--- a/src/lib/wallclock/include.am
+++ b/src/lib/wallclock/include.am
@@ -17,5 +17,6 @@ src_lib_libtor_wallclock_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
 
 noinst_HEADERS +=					\
 	src/lib/wallclock/approx_time.h			\
+	src/lib/wallclock/timeval.h			\
 	src/lib/wallclock/tm_cvt.h			\
 	src/lib/wallclock/tor_gettimeofday.h
diff --git a/src/lib/wallclock/timeval.c b/src/lib/wallclock/timeval.c
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/lib/wallclock/timeval.h b/src/lib/wallclock/timeval.h
new file mode 100644
index 000000000..6a9b36a02
--- /dev/null
+++ b/src/lib/wallclock/timeval.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_TIMEVAL_H
+#define TOR_TIMEVAL_H
+
+#include "orconfig.h"
+#include "lib/cc/torint.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifndef timeradd
+/** Replacement for timeradd on platforms that do not have it: sets tvout to
+ * the sum of tv1 and tv2. */
+#define timeradd(tv1,tv2,tvout) \
+  do {                                                  \
+    (tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec;    \
+    (tvout)->tv_usec = (tv1)->tv_usec + (tv2)->tv_usec; \
+    if ((tvout)->tv_usec >= 1000000) {                  \
+      (tvout)->tv_usec -= 1000000;                      \
+      (tvout)->tv_sec++;                                \
+    }                                                   \
+  } while (0)
+#endif /* !defined(timeradd) */
+
+#ifndef timersub
+/** Replacement for timersub on platforms that do not have it: sets tvout to
+ * tv1 minus tv2. */
+#define timersub(tv1,tv2,tvout) \
+  do {                                                  \
+    (tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec;    \
+    (tvout)->tv_usec = (tv1)->tv_usec - (tv2)->tv_usec; \
+    if ((tvout)->tv_usec < 0) {                         \
+      (tvout)->tv_usec += 1000000;                      \
+      (tvout)->tv_sec--;                                \
+    }                                                   \
+  } while (0)
+#endif /* !defined(timersub) */
+
+#ifndef timercmp
+/** Replacement for timercmp on platforms that do not have it: returns true
+ * iff the relational operator "op" makes the expression tv1 op tv2 true.
+ *
+ * Note that while this definition should work for all boolean operators, some
+ * platforms' native timercmp definitions do not support >=, <=, or ==.  So
+ * don't use those.
+ */
+#define timercmp(tv1,tv2,op)                    \
+  (((tv1)->tv_sec == (tv2)->tv_sec) ?           \
+   ((tv1)->tv_usec op (tv2)->tv_usec) :         \
+   ((tv1)->tv_sec op (tv2)->tv_sec))
+#endif /* !defined(timercmp) */
+
+#endif
diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c
index 08186ca9a..c2abb2d14 100644
--- a/src/or/circuitstats.c
+++ b/src/or/circuitstats.c
@@ -41,6 +41,7 @@
 #include "or/circuitlist.h"
 #include "or/circuituse.h"
 #include "lib/math/fp.h"
+#include "lib/time/tvdiff.h"
 
 #include "or/crypt_path_st.h"
 #include "or/origin_circuit_st.h"
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 3669eb7f1..71abd5d6c 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -57,6 +57,7 @@
 #include "or/router.h"
 #include "or/routerlist.h"
 #include "lib/math/fp.h"
+#include "lib/time/tvdiff.h"
 
 #include "or/cpath_build_state_st.h"
 #include "or/dir_connection_st.h"
diff --git a/src/or/geoip.c b/src/or/geoip.c
index 330477e4c..4a55e3f8d 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -39,6 +39,7 @@
 #include "or/routerlist.h"
 
 #include "lib/container/order.h"
+#include "lib/time/tvdiff.h"
 
 static void init_geoip_countries(void);
 
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 8fe308826..220b05b49 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -31,6 +31,7 @@
 #include "lib/thread/numcpus.h"
 #include "lib/math/fp.h"
 #include "lib/math/laplace.h"
+#include "lib/time/tvdiff.h"
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>





More information about the tor-commits mailing list