summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-06-16 10:16:04 -0400
committerNick Mathewson <nickm@torproject.org>2016-06-16 10:16:04 -0400
commit41cb26c1696b2e91f6ffe28c98ab471b925de9e8 (patch)
treeef4ab6198667a0fd44f4fb5085cf9306ffc6b3b5 /src
parentf05a213fe1706ce3ba76e12dc8e6f36f74c92794 (diff)
downloadtor-41cb26c1696b2e91f6ffe28c98ab471b925de9e8.tar.gz
tor-41cb26c1696b2e91f6ffe28c98ab471b925de9e8.zip
Correct the rounding behavior on tv_mdiff.
Fix for bug 19428.
Diffstat (limited to 'src')
-rw-r--r--src/common/util.c12
-rw-r--r--src/test/test_util.c4
2 files changed, 11 insertions, 5 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 2a3aec525a..d005dade53 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 dd600d96fc..83b48c9f59 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));