Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
26 | pmbaty | 1 | /* ACC -- Automatic Compiler Configuration |
2 | |||
3 | Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer |
||
4 | All Rights Reserved. |
||
5 | |||
6 | This software is a copyrighted work licensed under the terms of |
||
7 | the GNU General Public License. Please consult the file "ACC_LICENSE" |
||
8 | for details. |
||
9 | |||
10 | Markus F.X.J. Oberhumer |
||
11 | <markus@oberhumer.com> |
||
12 | http://www.oberhumer.com/ |
||
13 | */ |
||
14 | |||
15 | |||
16 | #define __ACCLIB_UCLOCK_CH_INCLUDED 1 |
||
17 | #if !defined(ACCLIB_PUBLIC) |
||
18 | # define ACCLIB_PUBLIC(r,f) r __ACCLIB_FUNCNAME(f) |
||
19 | #endif |
||
20 | |||
21 | |||
22 | #if (ACC_OS_DOS16 || ACC_OS_WIN16) |
||
23 | #elif (ACC_OS_DOS32 && ACC_CC_GNUC) && defined(__DJGPP__) |
||
24 | #elif (ACC_OS_CYGWIN || ACC_OS_WIN32 || ACC_OS_WIN64) && (ACC_HAVE_WINDOWS_H) |
||
25 | # if defined(acc_int64l_t) |
||
26 | /* See also: KB Q274323: PRB: Performance Counter Value May |
||
27 | * Unexpectedly Leap Forward */ |
||
28 | # define __ACCLIB_UCLOCK_USE_QPC 1 |
||
29 | # endif |
||
30 | /* fallbacks */ |
||
31 | # if ((ACC_CC_DMC && (__DMC__ < 0x838)) || ACC_CC_LCC) |
||
32 | /* winmm.lib is missing */ |
||
33 | # define __ACCLIB_UCLOCK_USE_CLOCK 1 |
||
34 | # else |
||
35 | # define __ACCLIB_UCLOCK_USE_WINMM 1 |
||
36 | # if (ACC_CC_MSC && (_MSC_VER >= 900)) |
||
37 | /* avoid `-W4' warnings in <mmsystem.h> */ |
||
38 | # pragma warning(disable: 4201) |
||
39 | # elif (ACC_CC_MWERKS) |
||
40 | /* avoid duplicate typedef in <mmsystem.h> */ |
||
41 | # define LPUINT __ACC_MMSYSTEM_H_LPUINT |
||
42 | # endif |
||
43 | # if 1 |
||
44 | # include <mmsystem.h> |
||
45 | # else |
||
46 | # if (ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_PELLESC) |
||
47 | ACC_EXTERN_C __declspec(dllimport) unsigned long __stdcall timeGetTime(void); |
||
48 | # else |
||
49 | ACC_EXTERN_C unsigned long __stdcall timeGetTime(void); |
||
50 | # endif |
||
51 | # endif |
||
52 | # if (ACC_CC_DMC) |
||
53 | # pragma DMC includelib "winmm.lib" |
||
54 | # elif (ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_PELLESC) |
||
55 | # pragma comment(lib, "winmm.lib") |
||
56 | # elif (ACC_CC_MWERKS && (__MWERKS__ >= 0x3000)) |
||
57 | # pragma comment(lib, "winmm.lib") |
||
58 | # elif (ACC_CC_SYMANTECC) |
||
59 | # pragma SC includelib "winmm.lib" |
||
60 | # elif (ACC_CC_WATCOMC && (__WATCOMC__ >= 1050)) |
||
61 | # pragma library("winmm.lib") |
||
62 | # endif |
||
63 | # endif |
||
64 | #elif (ACC_OS_EMX) && (ACC_HAVE_WINDOWS_H) && defined(acc_int64l_t) |
||
65 | # define __ACCLIB_UCLOCK_USE_QPC 1 |
||
66 | #elif (ACC_OS_CYGWIN || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_TOS || ACC_OS_WIN32 || ACC_OS_WIN64) |
||
67 | # define __ACCLIB_UCLOCK_USE_CLOCK 1 |
||
68 | #endif |
||
69 | |||
70 | #if (__ACCLIB_UCLOCK_USE_CLOCK) && !defined(CLOCKS_PER_SEC) |
||
71 | # if defined(CLK_TCK) |
||
72 | # define CLOCKS_PER_SEC CLK_TCK |
||
73 | # else |
||
74 | # undef __ACCLIB_UCLOCK_USE_CLOCK |
||
75 | # endif |
||
76 | #endif |
||
77 | |||
78 | |||
79 | /************************************************************************* |
||
80 | // |
||
81 | **************************************************************************/ |
||
82 | |||
83 | ACCLIB_PUBLIC(int, acc_uclock_open) (acc_uclock_handle_p h) |
||
84 | { |
||
85 | acc_uclock_t c; |
||
86 | int i; |
||
87 | |||
88 | #if (__ACCLIB_UCLOCK_USE_QPC) |
||
89 | LARGE_INTEGER li; |
||
90 | h->qpf = 0.0; |
||
91 | if (QueryPerformanceFrequency(&li) != 0) { |
||
92 | h->qpf = (double) li.QuadPart; |
||
93 | if (h->qpf <= 0.0 || QueryPerformanceCounter(&li) == 0) { |
||
94 | h->qpf = 0.0; |
||
95 | } |
||
96 | } |
||
97 | #elif (ACC_HAVE_WINDOWS_H) && defined(acc_int64l_t) |
||
98 | h->qpf = 0.0; |
||
99 | #endif |
||
100 | h->h = 1; |
||
101 | h->mode = 0; |
||
102 | |||
103 | /* warm up */ |
||
104 | i = 100; |
||
105 | do { |
||
106 | acc_uclock_read(h, &c); |
||
107 | #if (__ACCLIB_UCLOCK_USE_QPC) |
||
108 | if (h->qpf > 0.0 && c.qpc == 0) { h->qpf = 0.0; i = 100; } |
||
109 | #endif |
||
110 | } while (--i > 0); |
||
111 | |||
112 | return 0; |
||
113 | } |
||
114 | |||
115 | |||
116 | ACCLIB_PUBLIC(int, acc_uclock_close) (acc_uclock_handle_p h) |
||
117 | { |
||
118 | h->h = 0; |
||
119 | h->mode = -1; |
||
120 | return 0; |
||
121 | } |
||
122 | |||
123 | |||
124 | /************************************************************************* |
||
125 | // |
||
126 | **************************************************************************/ |
||
127 | |||
128 | ACCLIB_PUBLIC(void, acc_uclock_read) (acc_uclock_handle_p h, acc_uclock_p c) |
||
129 | { |
||
130 | #if (__ACCLIB_UCLOCK_USE_QPC) |
||
131 | if (h->qpf > 0.0) { |
||
132 | LARGE_INTEGER li; |
||
133 | if (QueryPerformanceCounter(&li) != 0) { |
||
134 | c->qpc = (acc_int64l_t) li.QuadPart; |
||
135 | if (c->qpc > 0) |
||
136 | return; |
||
137 | } |
||
138 | c->qpc = 0; /* failed */ |
||
139 | } |
||
140 | #elif (ACC_HAVE_WINDOWS_H) && defined(acc_int64l_t) |
||
141 | /* c->qpc = 0; */ |
||
142 | #endif |
||
143 | |||
144 | { |
||
145 | #if (ACC_OS_DOS16 || ACC_OS_WIN16) |
||
146 | # if (ACC_CC_AZTECC) |
||
147 | c->ticks.t32 = 0; |
||
148 | # else |
||
149 | union REGS ri, ro; |
||
150 | ri.x.ax = 0x2c00; int86(0x21, &ri, &ro); |
||
151 | c->ticks.t32 = ro.h.ch*60UL*60UL*100UL + ro.h.cl*60UL*100UL + ro.h.dh*100UL + ro.h.dl; |
||
152 | # endif |
||
153 | #elif (ACC_OS_DOS32 && ACC_CC_GNUC) && defined(__DJGPP__) |
||
154 | c->ticks.t64 = uclock(); |
||
155 | #elif (__ACCLIB_UCLOCK_USE_CLOCK) && defined(acc_int64l_t) |
||
156 | c->ticks.t64 = clock(); |
||
157 | #elif (__ACCLIB_UCLOCK_USE_CLOCK) |
||
158 | c->ticks.t32 = clock(); |
||
159 | #elif (__ACCLIB_UCLOCK_USE_WINMM) |
||
160 | c->ticks.t32 = timeGetTime(); |
||
161 | #elif (__ACCLIB_UCLOCK_USE_GETRUSAGE) |
||
162 | struct rusage ru; |
||
163 | if (getrusage(RUSAGE_SELF, &ru) != 0) c->ticks.rd = 0; |
||
164 | else c->ticks.td = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1000000.0; |
||
165 | #elif (HAVE_GETTIMEOFDAY) |
||
166 | struct timeval tv; |
||
167 | if (gettimeofday(&tv, 0) != 0) c->ticks.td = 0; |
||
168 | else c->ticks.td = tv.tv_sec + tv.tv_usec / 1000000.0; |
||
169 | #else |
||
170 | ACC_UNUSED(c); |
||
171 | #endif |
||
172 | } |
||
173 | ACC_UNUSED(h); |
||
174 | } |
||
175 | |||
176 | |||
177 | /************************************************************************* |
||
178 | // |
||
179 | **************************************************************************/ |
||
180 | |||
181 | ACCLIB_PUBLIC(double, acc_uclock_get_elapsed) (acc_uclock_handle_p h, const acc_uclock_p start, const acc_uclock_p stop) |
||
182 | { |
||
183 | double d; |
||
184 | |||
185 | if (!h->h) { |
||
186 | h->mode = -1; |
||
187 | return 0.0; |
||
188 | } |
||
189 | |||
190 | #if (__ACCLIB_UCLOCK_USE_QPC) |
||
191 | if (h->qpf > 0.0) { |
||
192 | h->mode = 1; |
||
193 | if (start->qpc == 0 || stop->qpc == 0) return 0.0; |
||
194 | return (double) (stop->qpc - start->qpc) / h->qpf; |
||
195 | } |
||
196 | #endif |
||
197 | |||
198 | #if (ACC_OS_DOS16 || ACC_OS_WIN16) |
||
199 | h->mode = 2; |
||
200 | d = (double) (stop->ticks.t32 - start->ticks.t32) / 100.0; |
||
201 | if (d < 0.0) d += 86400.0; /* midnight passed */ |
||
202 | #elif (ACC_OS_DOS32 && ACC_CC_GNUC) && defined(__DJGPP__) |
||
203 | h->mode = 3; |
||
204 | d = (double) (stop->ticks.t64 - start->ticks.t64) / (UCLOCKS_PER_SEC); |
||
205 | #elif (__ACCLIB_UCLOCK_USE_CLOCK) && defined(acc_int64l_t) |
||
206 | h->mode = 4; |
||
207 | d = (double) (stop->ticks.t64 - start->ticks.t64) / (CLOCKS_PER_SEC); |
||
208 | #elif (__ACCLIB_UCLOCK_USE_CLOCK) |
||
209 | h->mode = 5; |
||
210 | d = (double) (stop->ticks.t32 - start->ticks.t32) / (CLOCKS_PER_SEC); |
||
211 | #elif (__ACCLIB_UCLOCK_USE_WINMM) |
||
212 | h->mode = 6; |
||
213 | d = (double) (stop->ticks.t32 - start->ticks.t32) / 1000.0; |
||
214 | #elif (__ACCLIB_UCLOCK_USE_GETRUSAGE) |
||
215 | h->mode = 7; |
||
216 | d = stop->ticks.td - start->ticks.td; |
||
217 | #elif (HAVE_GETTIMEOFDAY) |
||
218 | h->mode = 8; |
||
219 | d = stop->ticks.td - start->ticks.td; |
||
220 | #else |
||
221 | h->mode = 0; |
||
222 | d = 0.0; |
||
223 | #endif |
||
224 | return d; |
||
225 | } |
||
226 | |||
227 | |||
228 | /* |
||
229 | vi:ts=4:et |
||
230 | */ |