summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%netscape.com <devnull@localhost>2002-12-12 14:55:55 +0000
committerwtc%netscape.com <devnull@localhost>2002-12-12 14:55:55 +0000
commit591860e699409045f9c2363085cca8c88459479c (patch)
treecb7e56c96c3aa229307d95dcb46b04f2643af065
parent0a508e249131b49fa474f117ca92acf01ce5bd84 (diff)
downloadnspr-hg-591860e699409045f9c2363085cca8c88459479c.tar.gz
Bug 176881: we should also look at the high 32 bits of the performance
counter frequency. Ignoring the high part of the frequency will cause our interval timer code to malfunction if the high part is not zero. Also took the opportunity to simplify the arithmetics. Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r--pr/src/md/windows/ntinrval.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/pr/src/md/windows/ntinrval.c b/pr/src/md/windows/ntinrval.c
index d6a3fe6f..857ada6a 100644
--- a/pr/src/md/windows/ntinrval.c
+++ b/pr/src/md/windows/ntinrval.c
@@ -45,9 +45,8 @@
#define QueryPerformanceCounter(x) FALSE
#endif
-PRIntn _nt_bitShift = 0;
-PRInt32 _nt_highMask = 0;
-PRInt32 _nt_ticksPerSec = -1;
+static PRIntn _nt_bitShift = 0;
+static PRInt32 _nt_ticksPerSec = -1;
void
_PR_MD_INTERVAL_INIT()
@@ -55,16 +54,33 @@ _PR_MD_INTERVAL_INIT()
LARGE_INTEGER count;
if (QueryPerformanceFrequency(&count)) {
+ /*
+ * HighPart is signed (LONG). Assert that its sign bit is 0
+ * because we will be right shifting it. LowPart is unsigned
+ * (DWORD).
+ */
+ PR_ASSERT(count.HighPart >= 0);
+ while(count.HighPart) {
+ count.LowPart = (count.HighPart << 31) + (count.LowPart >> 1);
+ count.HighPart >>= 1;
+ _nt_bitShift++;
+ }
while(count.LowPart > PR_INTERVAL_MAX) {
count.LowPart >>= 1;
_nt_bitShift++;
- _nt_highMask = (_nt_highMask << 1)+1;
}
- _nt_ticksPerSec = count.LowPart;
- PR_ASSERT(_nt_ticksPerSec > PR_INTERVAL_MIN);
- } else
- _nt_ticksPerSec = -1;
+ /*
+ * We can't use the performance counter if after
+ * normalization we are left with fewer than 32 bits.
+ */
+ if (_nt_bitShift <= 32) {
+ _nt_ticksPerSec = count.LowPart;
+ PR_ASSERT(_nt_ticksPerSec > PR_INTERVAL_MIN);
+ return;
+ }
+ }
+ _nt_ticksPerSec = -1;
}
PRIntervalTime
@@ -76,12 +92,15 @@ _PR_MD_GET_INTERVAL()
* to only 100000 ticks per second; QueryPerformanceCounter is too high
* resolution...
*/
- if (QueryPerformanceCounter(&count)) {
- PRInt32 top = count.HighPart & _nt_highMask;
- top = top << (32 - _nt_bitShift);
- count.LowPart = count.LowPart >> _nt_bitShift;
- count.LowPart = count.LowPart + top;
- return (PRUint32)count.LowPart;
+ if (_nt_ticksPerSec != -1) {
+ (void)QueryPerformanceCounter(&count);
+ PR_ASSERT(_nt_bitShift <= 32);
+ if (_nt_bitShift == 32) {
+ return (PRUint32)count.HighPart;
+ } else {
+ return (PRUint32)((count.HighPart << (32 - _nt_bitShift))
+ + (count.LowPart >> _nt_bitShift));
+ }
} else
#if defined(__MINGW32__)
return time();