From 906d6413ebd8a3d42aee8fa1430491bfededc907 Mon Sep 17 00:00:00 2001 From: "wtc%netscape.com" Date: Fri, 28 Feb 2003 02:46:12 +0000 Subject: [PATCH] Bug 164841: use high performance timers (again) on OS/2. --- nsprpub/pr/src/md/os2/os2inrval.c | 48 ++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/nsprpub/pr/src/md/os2/os2inrval.c b/nsprpub/pr/src/md/os2/os2inrval.c index 5c112531a7f8..d4c900733470 100644 --- a/nsprpub/pr/src/md/os2/os2inrval.c +++ b/nsprpub/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; + } }