From a097ddb4f5105d33146eb8f6afa7d6cd01d47fea Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 28 Jun 2018 12:57:01 -0400 Subject: [PATCH] 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(-) create mode 100644 src/lib/time/.may_include rename src/{common => lib/time}/compat_time.c (99%) rename src/{common => lib/time}/compat_time.h (99%) create mode 100644 src/lib/time/include.am create mode 100644 src/lib/time/tvdiff.c create mode 100644 src/lib/time/tvdiff.h create mode 100644 src/lib/wallclock/timeval.c create mode 100644 src/lib/wallclock/timeval.h diff --git a/.gitignore b/.gitignore index c940166aa8..0b45af3b6d 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 5a7271e30f..d28eb61493 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 5cd8e72154..582945734c 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 #include /* ===== 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 2d7297665c..bb1a3ee420 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 e1fae0deab..b31bb834e1 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 3068f023a4..f174cd3667 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 8345813b71..ba5421e093 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 0000000000..a35e7a34e1 --- /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 148f2f8957..f50ccb5e3d 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 @@ -20,6 +25,9 @@ #ifdef HAVE_SYS_TYPES_H #include #endif +#ifdef HAVE_SYS_TIME_H +#include +#endif #ifdef HAVE_UNISTD_H #include #endif @@ -34,9 +42,9 @@ #include #endif -#include "lib/err/torerr.h" -#include "lib/log/torlog.h" -#include "common/util.h" +#include +#include +#include #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 2f7e87a633..4427ce8f92 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 0000000000..a3f93a3744 --- /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 0000000000..11c881234a --- /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 0000000000..215de9cf37 --- /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 7b735e97ee..7864c21e16 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 0000000000..e69de29bb2 diff --git a/src/lib/wallclock/timeval.h b/src/lib/wallclock/timeval.h new file mode 100644 index 0000000000..6a9b36a022 --- /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 +#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 08186ca9a9..c2abb2d14b 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 3669eb7f16..71abd5d6ce 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 330477e4ce..4a55e3f8db 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 8fe308826b..220b05b49b 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