From: Howard Chu Date: Thu, 11 Sep 2008 01:51:02 +0000 (+0000) Subject: ITS#5668 avoid overflows in Windows microsecond computation X-Git-Tag: ACLCHECK_0~1358 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=178141d7ec971e7dc6d5f01d94ad4e1eca07a4c0;p=openldap ITS#5668 avoid overflows in Windows microsecond computation --- diff --git a/libraries/liblutil/utils.c b/libraries/liblutil/utils.c index 63b0f3802a..8a199f85dd 100644 --- a/libraries/liblutil/utils.c +++ b/libraries/liblutil/utils.c @@ -303,41 +303,52 @@ lutil_gettime( struct lutil_tm *tm ) GetSystemTime( &st ); QueryPerformanceCounter( &count ); + /* It shouldn't ever go backwards, but multiple CPUs might + * be able to hit in the same tick. + */ + if ( count.QuadPart <= prevCount.QuadPart ) { + subs++; + } else { + subs = 0; + prevCount = count; + } + /* We assume Windows has at least a vague idea of * when a second begins. So we align our microsecond count * with the Windows millisecond count using this offset. * We retain the submillisecond portion of our own count. + * + * Note - this also assumes that the relationship between + * the PerformanceCouunter and SystemTime stays constant; + * that assumption breaks if the SystemTime is adjusted by + * an external action. */ if ( !cFreq.QuadPart ) { long long t; int usec; QueryPerformanceFrequency( &cFreq ); - t = count.QuadPart * 1000000; - t /= cFreq.QuadPart; - usec = t % 10000000; - usec /= 1000; - offset = ( usec - st.wMilliseconds ) * 1000; - } + /* just get sub-second portion of counter */ + t = count.QuadPart % cFreq.QuadPart; - /* It shouldn't ever go backwards, but multiple CPUs might - * be able to hit in the same tick. - */ - if ( count.QuadPart <= prevCount.QuadPart ) { - subs++; - } else { - subs = 0; - prevCount = count; + /* convert to microseconds */ + t *= 1000000; + usec = t / cFreq.QuadPart; + + offset = usec - st.wMilliseconds * 1000; } tm->tm_usub = subs; /* convert to microseconds */ + count.QuadPart %= cFreq.QuadPart; count.QuadPart *= 1000000; count.QuadPart /= cFreq.QuadPart; count.QuadPart -= offset; tm->tm_usec = count.QuadPart % 1000000; + if ( tm->tm_usec < 0 ) + tm->tm_usec += 1000000; /* any difference larger than microseconds is * already reflected in st