[tor-commits] [tor/master] Correct the rounding behavior on tv_mdiff.

nickm at torproject.org nickm at torproject.org
Thu Jun 16 14:16:23 UTC 2016


commit 41cb26c1696b2e91f6ffe28c98ab471b925de9e8
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Jun 16 10:16:04 2016 -0400

    Correct the rounding behavior on tv_mdiff.
    
    Fix for bug 19428.
---
 changes/bug19428     |  5 +++++
 src/common/util.c    | 12 +++++++++---
 src/test/test_util.c |  4 ++--
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/changes/bug19428 b/changes/bug19428
new file mode 100644
index 0000000..32d293e
--- /dev/null
+++ b/changes/bug19428
@@ -0,0 +1,5 @@
+  - Minor bugfixes (timing):
+    o When computing the difference between two times in milliseconds,
+      we now round to the nearest millisecond correctly. Previously,
+      we could sometimes round in the wrong direction. Fixes bug 19428;
+      bugfix on 0.2.2.2-alpha.
diff --git a/src/common/util.c b/src/common/util.c
index 2a3aec5..d005dad 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1386,7 +1386,7 @@ tv_udiff(const struct timeval *start, const struct timeval *end)
   long udiff;
   long secdiff = end->tv_sec - start->tv_sec;
 
-  if (labs(secdiff+1) > LONG_MAX/1000000) {
+  if (labs(secdiff)+1 > LONG_MAX/1000000) {
     log_warn(LD_GENERAL, "comparing times on microsecond detail too far "
              "apart: %ld seconds", secdiff);
     return LONG_MAX;
@@ -1404,7 +1404,7 @@ tv_mdiff(const struct timeval *start, const struct timeval *end)
   long mdiff;
   long secdiff = end->tv_sec - start->tv_sec;
 
-  if (labs(secdiff+1) > LONG_MAX/1000) {
+  if (labs(secdiff)+1 > LONG_MAX/1000) {
     log_warn(LD_GENERAL, "comparing times on millisecond detail too far "
              "apart: %ld seconds", secdiff);
     return LONG_MAX;
@@ -1412,7 +1412,13 @@ tv_mdiff(const struct timeval *start, const struct timeval *end)
 
   /* Subtract and round */
   mdiff = secdiff*1000L +
-      ((long)end->tv_usec - (long)start->tv_usec + 500L) / 1000L;
+      /* 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.
+       */
+      ((long)end->tv_usec - (long)start->tv_usec + 500L + 1000000L) / 1000L
+      - 1000;
   return mdiff;
 }
 
diff --git a/src/test/test_util.c b/src/test/test_util.c
index dd600d9..83b48c9 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -286,12 +286,12 @@ test_util_time(void *arg)
   end.tv_usec = 0;
 
   tt_int_op(995000L,OP_EQ, tv_udiff(&start, &end));
-  // tt_int_op(996L,OP_EQ, tv_mdiff(&start, &end)); // XXXX fails
+  tt_int_op(995L,OP_EQ, tv_mdiff(&start, &end));
 
   end.tv_sec = 4;
 
   tt_int_op(-1005000L,OP_EQ, tv_udiff(&start, &end));
-  // tt_int_op(-1005L,OP_EQ, tv_udiff(&start, &end)); // XXXX Fails
+  tt_int_op(-1005L,OP_EQ, tv_mdiff(&start, &end));
 
   end.tv_sec = TIME_MAX;
   tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));



More information about the tor-commits mailing list