diff options
author | wtc%netscape.com <devnull@localhost> | 2003-02-28 02:44:25 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2003-02-28 02:44:25 +0000 |
commit | cc4ab57d52d2f19b79dc1ae518168e03e3a109aa (patch) | |
tree | fa31be766d5faf492f2a49148a1aebba083c9a7c | |
parent | 031797f4a5fa2fb97ecb5dc91c6894d533b35559 (diff) | |
download | nspr-hg-cc4ab57d52d2f19b79dc1ae518168e03e3a109aa.tar.gz |
Bug 164841: use high performance timers (again) on OS/2.
Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r-- | pr/src/md/os2/os2inrval.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/pr/src/md/os2/os2inrval.c b/pr/src/md/os2/os2inrval.c index 5c112531..d4c90073 100644 --- a/pr/src/md/os2/os2inrval.c +++ b/pr/src/md/os2/os2inrval.c @@ -39,22 +39,62 @@ #include "primpl.h" +static PRBool useHighResTimer = PR_FALSE; +PRIntervalTime _os2_ticksPerSec = -1; +PRIntn _os2_bitShift = 0; +PRInt32 _os2_highMask = 0; void _PR_MD_INTERVAL_INIT() { + ULONG timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */ + APIRET rc = DosTmrQueryFreq(&timerFreq); + if (NO_ERROR == rc) { + useHighResTimer = PR_TRUE; + PR_ASSERT(timerFreq != 0); + while (timerFreq > PR_INTERVAL_MAX) { + timerFreq >>= 1; + _os2_bitShift++; + _os2_highMask = (_os2_highMask << 1)+1; + } + + _os2_ticksPerSec = timerFreq; + PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN); + } } PRIntervalTime _PR_MD_GET_INTERVAL() { - ULONG msCount = PR_FAILURE; - DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount)); - return msCount; + if (useHighResTimer) { + QWORD timestamp; + PRInt32 top; + APIRET rc = DosTmrQueryTime(×tamp); + if (NO_ERROR != rc) { + return -1; + } + /* Sadly, nspr requires the interval to range from 1000 ticks per + * second to only 100000 ticks per second. DosTmrQueryTime is too + * high resolution... + */ + top = timestamp.ulHi & _os2_highMask; + top = top << (32 - _os2_bitShift); + timestamp.ulLo = timestamp.ulLo >> _os2_bitShift; + timestamp.ulLo = timestamp.ulLo + top; + return (PRUint32)timestamp.ulLo; + } else { + ULONG msCount = -1; + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount)); + return msCount; + } } PRIntervalTime _PR_MD_INTERVAL_PER_SEC() { - return 1000; + if (useHighResTimer) { + return _os2_ticksPerSec; + } else { + return 1000; + } } |