From bc0aaa9217d1ca85dbb0f7a5452a0705e7a28264 Mon Sep 17 00:00:00 2001 From: John Hasler Date: Tue, 29 Apr 2008 12:40:15 -0500 Subject: [PATCH] Fix fault where chronyd enters an endless loop on x86_64 John writes: Here is a patch that should prevent the endless loop. I've changed UTI_NormaliseTimeval() to use divide/remainder instead of a loop. It also replaces some similar loops with calls to UTI_NormaliseTimeval() and fixes an unrelated bug in UTI_DiffTimevals(). --- util.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/util.c b/util.c index 431be1e..d506ffd 100644 --- a/util.c +++ b/util.c @@ -87,15 +87,17 @@ UTI_CompareTimevals(struct timeval *a, struct timeval *b) INLINE_STATIC void UTI_NormaliseTimeval(struct timeval *x) { - while (x->tv_usec >= 1000000) { - ++x->tv_sec; - x->tv_usec -= 1000000; + /* Reduce tv_usec to within +-1000000 of zero. JGH */ + if ((x->tv_usec >= 1000000) || (x->tv_usec <= -1000000)) { + x->tv_sec += x->tv_usec/1000000; + x->tv_usec = x->tv_usec%1000000; } - while (x->tv_usec < 0) { + /* Make tv_usec positive. JGH */ + if (x->tv_usec < 0) { --x->tv_sec; x->tv_usec += 1000000; - } + } } @@ -110,17 +112,9 @@ UTI_DiffTimevals(struct timeval *result, result->tv_usec = a->tv_usec - b->tv_usec; /* Correct microseconds field to bring it into the range - [0,1000000) */ + (0,1000000) */ - while (result->tv_usec < 0) { - result->tv_usec += 1000000; - --result->tv_sec; - } - - while (result->tv_usec > 999999) { - result->tv_usec -= 1000000; - ++result->tv_sec; - } + UTI_NormaliseTimeval(result); /* JGH */ return; } @@ -191,7 +185,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier, } tvhalf.tv_sec = tvdiff.tv_sec / 2; - tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2); + tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2) * 500000; /* JGH */ average->tv_sec = earlier->tv_sec + tvhalf.tv_sec; average->tv_usec = earlier->tv_usec + tvhalf.tv_usec; @@ -199,17 +193,7 @@ UTI_AverageDiffTimevals (struct timeval *earlier, /* Bring into range */ UTI_NormaliseTimeval(average); - while (average->tv_usec >= 1000000) { - ++average->tv_sec; - average->tv_usec -= 1000000; - } - - while (average->tv_usec < 0) { - --average->tv_sec; - average->tv_usec += 1000000; - } - -} + } /* ================================================== */