|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 /* |
|
7 * OS/2 interval timers |
|
8 * |
|
9 */ |
|
10 |
|
11 #include "primpl.h" |
|
12 |
|
13 static PRBool useHighResTimer = PR_FALSE; |
|
14 PRIntervalTime _os2_ticksPerSec = -1; |
|
15 PRIntn _os2_bitShift = 0; |
|
16 PRInt32 _os2_highMask = 0; |
|
17 |
|
18 void |
|
19 _PR_MD_INTERVAL_INIT() |
|
20 { |
|
21 char *envp; |
|
22 ULONG timerFreq; |
|
23 APIRET rc; |
|
24 |
|
25 if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) { |
|
26 if (atoi(envp) == 1) |
|
27 return; |
|
28 } |
|
29 |
|
30 timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */ |
|
31 rc = DosTmrQueryFreq(&timerFreq); |
|
32 if (NO_ERROR == rc) { |
|
33 useHighResTimer = PR_TRUE; |
|
34 PR_ASSERT(timerFreq != 0); |
|
35 while (timerFreq > PR_INTERVAL_MAX) { |
|
36 timerFreq >>= 1; |
|
37 _os2_bitShift++; |
|
38 _os2_highMask = (_os2_highMask << 1)+1; |
|
39 } |
|
40 |
|
41 _os2_ticksPerSec = timerFreq; |
|
42 PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN); |
|
43 } |
|
44 } |
|
45 |
|
46 PRIntervalTime |
|
47 _PR_MD_GET_INTERVAL() |
|
48 { |
|
49 if (useHighResTimer) { |
|
50 QWORD timestamp; |
|
51 PRInt32 top; |
|
52 APIRET rc = DosTmrQueryTime(×tamp); |
|
53 if (NO_ERROR != rc) { |
|
54 return -1; |
|
55 } |
|
56 /* Sadly, nspr requires the interval to range from 1000 ticks per |
|
57 * second to only 100000 ticks per second. DosTmrQueryTime is too |
|
58 * high resolution... |
|
59 */ |
|
60 top = timestamp.ulHi & _os2_highMask; |
|
61 top = top << (32 - _os2_bitShift); |
|
62 timestamp.ulLo = timestamp.ulLo >> _os2_bitShift; |
|
63 timestamp.ulLo = timestamp.ulLo + top; |
|
64 return (PRUint32)timestamp.ulLo; |
|
65 } else { |
|
66 ULONG msCount = -1; |
|
67 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount)); |
|
68 return msCount; |
|
69 } |
|
70 } |
|
71 |
|
72 PRIntervalTime |
|
73 _PR_MD_INTERVAL_PER_SEC() |
|
74 { |
|
75 if (useHighResTimer) { |
|
76 return _os2_ticksPerSec; |
|
77 } else { |
|
78 return 1000; |
|
79 } |
|
80 } |