rf_etimer.h revision 1.1 1 1.1 oster /* $NetBSD: rf_etimer.h,v 1.1 1998/11/13 04:20:29 oster Exp $ */
2 1.1 oster /*
3 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
4 1.1 oster * All rights reserved.
5 1.1 oster *
6 1.1 oster * Author: Mark Holland
7 1.1 oster *
8 1.1 oster * Permission to use, copy, modify and distribute this software and
9 1.1 oster * its documentation is hereby granted, provided that both the copyright
10 1.1 oster * notice and this permission notice appear in all copies of the
11 1.1 oster * software, derivative works or modified versions, and any portions
12 1.1 oster * thereof, and that both notices appear in supporting documentation.
13 1.1 oster *
14 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 1.1 oster *
18 1.1 oster * Carnegie Mellon requests users of this software to return to
19 1.1 oster *
20 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 1.1 oster * School of Computer Science
22 1.1 oster * Carnegie Mellon University
23 1.1 oster * Pittsburgh PA 15213-3890
24 1.1 oster *
25 1.1 oster * any improvements or extensions that they make and grant Carnegie the
26 1.1 oster * rights to redistribute these changes.
27 1.1 oster */
28 1.1 oster
29 1.1 oster /* rf_etimer.h -- header file for code related to accurate timing
30 1.1 oster * This code currently assumes that the elapsed time between START_TIMER
31 1.1 oster * and START_TIMER is less than the period of the cycle counter. This
32 1.1 oster * means the events you want to time must be less than:
33 1.1 oster * clock speed max time
34 1.1 oster * ---------- --------
35 1.1 oster * 175 MHz 24 sec
36 1.1 oster * 150 MHz 28 sec
37 1.1 oster * 125 MHz 34 sec
38 1.1 oster *
39 1.1 oster *
40 1.1 oster * :
41 1.1 oster * Log: rf_etimer.h,v
42 1.1 oster * Revision 1.32 1996/08/13 18:11:09 jimz
43 1.1 oster * want MACH&&!__osf__, not just MACH for mach timing (MACH defined under OSF/1)
44 1.1 oster *
45 1.1 oster * Revision 1.31 1996/08/12 20:11:38 jimz
46 1.1 oster * use read_real_time() on AIX4+
47 1.1 oster *
48 1.1 oster * Revision 1.30 1996/08/09 18:48:12 jimz
49 1.1 oster * for now, use gettimeofday() on MACH
50 1.1 oster * (should eventually use better clock stuff)
51 1.1 oster *
52 1.1 oster * Revision 1.29 1996/08/07 21:09:08 jimz
53 1.1 oster * add IRIX as a gettimeofday system
54 1.1 oster *
55 1.1 oster * Revision 1.28 1996/08/06 22:25:23 jimz
56 1.1 oster * add LINUX_I386
57 1.1 oster *
58 1.1 oster * Revision 1.27 1996/07/30 04:45:53 jimz
59 1.1 oster * add ultrix stuff
60 1.1 oster *
61 1.1 oster * Revision 1.26 1996/07/28 20:31:39 jimz
62 1.1 oster * i386netbsd port
63 1.1 oster * true/false fixup
64 1.1 oster *
65 1.1 oster * Revision 1.25 1996/07/27 23:36:08 jimz
66 1.1 oster * Solaris port of simulator
67 1.1 oster *
68 1.1 oster * Revision 1.24 1996/07/27 18:40:24 jimz
69 1.1 oster * cleanup sweep
70 1.1 oster *
71 1.1 oster * Revision 1.23 1996/07/22 19:52:16 jimz
72 1.1 oster * switched node params to RF_DagParam_t, a union of
73 1.1 oster * a 64-bit int and a void *, for better portability
74 1.1 oster * attempted hpux port, but failed partway through for
75 1.1 oster * lack of a single C compiler capable of compiling all
76 1.1 oster * source files
77 1.1 oster *
78 1.1 oster * Revision 1.22 1996/07/18 22:57:14 jimz
79 1.1 oster * port simulator to AIX
80 1.1 oster *
81 1.1 oster * Revision 1.21 1996/07/17 21:00:58 jimz
82 1.1 oster * clean up timer interface, tracing
83 1.1 oster *
84 1.1 oster * Revision 1.20 1996/07/17 14:26:28 jimz
85 1.1 oster * rf_scc -> rf_rpcc
86 1.1 oster *
87 1.1 oster * Revision 1.19 1996/06/14 21:24:48 jimz
88 1.1 oster * move out ConfigureEtimer
89 1.1 oster *
90 1.1 oster * Revision 1.18 1996/06/03 23:28:26 jimz
91 1.1 oster * more bugfixes
92 1.1 oster * check in tree to sync for IPDS runs with current bugfixes
93 1.1 oster * there still may be a problem with threads in the script test
94 1.1 oster * getting I/Os stuck- not trivially reproducible (runs ~50 times
95 1.1 oster * in a row without getting stuck)
96 1.1 oster *
97 1.1 oster * Revision 1.17 1996/05/30 23:22:16 jimz
98 1.1 oster * bugfixes of serialization, timing problems
99 1.1 oster * more cleanup
100 1.1 oster *
101 1.1 oster * Revision 1.16 1996/05/30 12:59:18 jimz
102 1.1 oster * make etimer happier, more portable
103 1.1 oster *
104 1.1 oster * Revision 1.15 1996/05/27 18:56:37 jimz
105 1.1 oster * more code cleanup
106 1.1 oster * better typing
107 1.1 oster * compiles in all 3 environments
108 1.1 oster *
109 1.1 oster * Revision 1.14 1996/05/23 21:46:35 jimz
110 1.1 oster * checkpoint in code cleanup (release prep)
111 1.1 oster * lots of types, function names have been fixed
112 1.1 oster *
113 1.1 oster * Revision 1.13 1996/05/23 00:33:23 jimz
114 1.1 oster * code cleanup: move all debug decls to rf_options.c, all extern
115 1.1 oster * debug decls to rf_options.h, all debug vars preceded by rf_
116 1.1 oster *
117 1.1 oster * Revision 1.12 1996/05/18 19:51:34 jimz
118 1.1 oster * major code cleanup- fix syntax, make some types consistent,
119 1.1 oster * add prototypes, clean out dead code, et cetera
120 1.1 oster *
121 1.1 oster * Revision 1.11 1995/12/01 18:10:40 root
122 1.1 oster * added copyright info
123 1.1 oster *
124 1.1 oster * Revision 1.10 1995/09/29 14:27:32 wvcii
125 1.1 oster * removed printfs from ConfigureEtimer()
126 1.1 oster *
127 1.1 oster * Revision 1.9 95/09/19 22:57:31 jimz
128 1.1 oster * added kernel version of ConfigureEtimer
129 1.1 oster *
130 1.1 oster * Revision 1.8 1995/09/14 13:03:04 amiri
131 1.1 oster * set default CPU speed to 125Mhz to avoid divide by zero problems.
132 1.1 oster *
133 1.1 oster * Revision 1.7 1995/09/11 19:04:36 wvcii
134 1.1 oster * timer autoconfigs using pdl routine to check cpu speed
135 1.1 oster * value may still be overridden via config debug var timerTicksPerSec
136 1.1 oster *
137 1.1 oster */
138 1.1 oster
139 1.1 oster
140 1.1 oster #ifndef _RF__RF_TIMER_H_
141 1.1 oster #define _RF__RF_TIMER_H_
142 1.1 oster
143 1.1 oster #include "rf_options.h"
144 1.1 oster
145 1.1 oster #ifdef _KERNEL
146 1.1 oster #define KERNEL
147 1.1 oster #endif
148 1.1 oster
149 1.1 oster #ifdef __NetBSD__
150 1.1 oster
151 1.1 oster #ifdef KERNEL
152 1.1 oster extern unsigned int rpcc(void);
153 1.1 oster #define rf_read_cycle_counter rpcc
154 1.1 oster #else /* KERNEL */
155 1.1 oster #ifndef __NetBSD__
156 1.1 oster /* XXX does this function even exist anywhere??? GO */
157 1.1 oster extern unsigned int rf_rpcc();
158 1.1 oster #endif
159 1.1 oster #define rf_read_cycle_counter rf_rpcc
160 1.1 oster #endif /* KERNEL */
161 1.1 oster
162 1.1 oster #define RF_DEF_TIMER_MAX_VAL 0xFFFFFFFF
163 1.1 oster
164 1.1 oster typedef struct RF_EtimerVal_s {
165 1.1 oster unsigned ccnt; /* cycle count */
166 1.1 oster } RF_EtimerVal_t;
167 1.1 oster
168 1.1 oster struct RF_Etimer_s {
169 1.1 oster RF_EtimerVal_t st;
170 1.1 oster RF_EtimerVal_t et;
171 1.1 oster unsigned long ticks; /* elapsed time in ticks */
172 1.1 oster };
173 1.1 oster
174 1.1 oster extern long rf_timer_max_val;
175 1.1 oster extern long rf_timer_ticks_per_second;
176 1.1 oster extern unsigned long rf_timer_ticks_per_usec;
177 1.1 oster
178 1.1 oster #define RF_ETIMER_TICKS2US(_tcks_) ( (_tcks_) / rf_timer_ticks_per_usec )
179 1.1 oster #define RF_ETIMER_START(_t_) { (_t_).st.ccnt = rf_read_cycle_counter(); }
180 1.1 oster #define RF_ETIMER_STOP(_t_) { (_t_).et.ccnt = rf_read_cycle_counter(); }
181 1.1 oster #define RF_ETIMER_EVAL(_t_) { \
182 1.1 oster if ((_t_).st.ccnt < (_t_).et.ccnt) \
183 1.1 oster (_t_).ticks = (_t_).et.ccnt - (_t_).st.ccnt; \
184 1.1 oster else \
185 1.1 oster (_t_).ticks = rf_timer_max_val - ((_t_).st.ccnt - (_t_).et.ccnt); \
186 1.1 oster }
187 1.1 oster
188 1.1 oster #define RF_ETIMER_VAL_TICKS(_t_) ((_t_).ticks)
189 1.1 oster #define RF_ETIMER_VAL_US(_t_) (RF_ETIMER_TICKS2US((_t_).ticks))
190 1.1 oster #define RF_ETIMER_VAL_MS(_t_) (RF_ETIMER_TICKS2US((_t_).ticks)/1000)
191 1.1 oster
192 1.1 oster #endif /* __NetBSD__ */
193 1.1 oster
194 1.1 oster
195 1.1 oster #if defined(__alpha) && !defined(__NetBSD__)
196 1.1 oster
197 1.1 oster #ifdef KERNEL
198 1.1 oster extern unsigned int rpcc();
199 1.1 oster #define rf_read_cycle_counter rpcc
200 1.1 oster #else /* KERNEL */
201 1.1 oster extern unsigned int rf_rpcc();
202 1.1 oster #define rf_read_cycle_counter rf_rpcc
203 1.1 oster #endif /* KERNEL */
204 1.1 oster
205 1.1 oster #define RF_DEF_TIMER_MAX_VAL 0xFFFFFFFF
206 1.1 oster
207 1.1 oster typedef struct RF_EtimerVal_s {
208 1.1 oster unsigned ccnt; /* cycle count */
209 1.1 oster } RF_EtimerVal_t;
210 1.1 oster
211 1.1 oster struct RF_Etimer_s {
212 1.1 oster RF_EtimerVal_t st;
213 1.1 oster RF_EtimerVal_t et;
214 1.1 oster unsigned long ticks; /* elapsed time in ticks */
215 1.1 oster };
216 1.1 oster
217 1.1 oster extern long rf_timer_max_val;
218 1.1 oster extern long rf_timer_ticks_per_second;
219 1.1 oster extern unsigned long rf_timer_ticks_per_usec;
220 1.1 oster
221 1.1 oster #define RF_ETIMER_TICKS2US(_tcks_) ( (_tcks_) / rf_timer_ticks_per_usec )
222 1.1 oster #define RF_ETIMER_START(_t_) { (_t_).st.ccnt = rf_read_cycle_counter(); }
223 1.1 oster #define RF_ETIMER_STOP(_t_) { (_t_).et.ccnt = rf_read_cycle_counter(); }
224 1.1 oster #define RF_ETIMER_EVAL(_t_) { \
225 1.1 oster if ((_t_).st.ccnt < (_t_).et.ccnt) \
226 1.1 oster (_t_).ticks = (_t_).et.ccnt - (_t_).st.ccnt; \
227 1.1 oster else \
228 1.1 oster (_t_).ticks = rf_timer_max_val - ((_t_).st.ccnt - (_t_).et.ccnt); \
229 1.1 oster }
230 1.1 oster
231 1.1 oster #define RF_ETIMER_VAL_TICKS(_t_) ((_t_).ticks)
232 1.1 oster #define RF_ETIMER_VAL_US(_t_) (RF_ETIMER_TICKS2US((_t_).ticks))
233 1.1 oster #define RF_ETIMER_VAL_MS(_t_) (RF_ETIMER_TICKS2US((_t_).ticks)/1000)
234 1.1 oster
235 1.1 oster #endif /* __alpha */
236 1.1 oster
237 1.1 oster #ifdef _IBMR2
238 1.1 oster
239 1.1 oster extern void rf_rtclock(unsigned int *secs, unsigned int *nsecs);
240 1.1 oster
241 1.1 oster #define RF_MSEC_PER_SEC 1000
242 1.1 oster #define RF_USEC_PER_SEC 1000000
243 1.1 oster #define RF_NSEC_PER_SEC 1000000000
244 1.1 oster
245 1.1 oster typedef struct RF_EtimerVal_s {
246 1.1 oster unsigned int secs;
247 1.1 oster unsigned int nsecs;
248 1.1 oster } RF_EtimerVal_t;
249 1.1 oster
250 1.1 oster struct RF_Etimer_s {
251 1.1 oster RF_EtimerVal_t start;
252 1.1 oster RF_EtimerVal_t end;
253 1.1 oster RF_EtimerVal_t elapsed;
254 1.1 oster };
255 1.1 oster
256 1.1 oster #if RF_AIXVERS >= 4
257 1.1 oster
258 1.1 oster #include <sys/time.h>
259 1.1 oster
260 1.1 oster #define RF_ETIMER_START(_t_) { \
261 1.1 oster timebasestruct_t tb; \
262 1.1 oster tb.flag = 1; \
263 1.1 oster read_real_time(&tb, TIMEBASE_SZ); \
264 1.1 oster (_t_).start.secs = tb.tb_high; \
265 1.1 oster (_t_).start.nsecs = tb.tb_low; \
266 1.1 oster }
267 1.1 oster
268 1.1 oster #define RF_ETIMER_STOP(_t_) { \
269 1.1 oster timebasestruct_t tb; \
270 1.1 oster tb.flag = 1; \
271 1.1 oster read_real_time(&tb, TIMEBASE_SZ); \
272 1.1 oster (_t_).end.secs = tb.tb_high; \
273 1.1 oster (_t_).end.nsecs = tb.tb_low; \
274 1.1 oster }
275 1.1 oster
276 1.1 oster #else /* RF_AIXVERS >= 4 */
277 1.1 oster
278 1.1 oster #define RF_ETIMER_START(_t_) { \
279 1.1 oster rf_rtclock(&((_t_).start.secs), &((_t_).start.nsecs)); \
280 1.1 oster }
281 1.1 oster
282 1.1 oster #define RF_ETIMER_STOP(_t_) { \
283 1.1 oster rf_rtclock(&((_t_).end.secs), &((_t_).end.nsecs)); \
284 1.1 oster }
285 1.1 oster
286 1.1 oster #endif /* RF_AIXVERS >= 4 */
287 1.1 oster
288 1.1 oster #define RF_ETIMER_EVAL(_t_) { \
289 1.1 oster if ((_t_).end.nsecs >= (_t_).start.nsecs) { \
290 1.1 oster (_t_).elapsed.nsecs = (_t_).end.nsecs - (_t_).start.nsecs; \
291 1.1 oster (_t_).elapsed.secs = (_t_).end.secs - (_t_).start.nsecs; \
292 1.1 oster } \
293 1.1 oster else { \
294 1.1 oster (_t_).elapsed.nsecs = RF_NSEC_PER_SEC + (_t_).end.nsecs; \
295 1.1 oster (_t_).elapsed.nsecs -= (_t_).start.nsecs; \
296 1.1 oster (_t_).elapsed.secs = (_t_).end.secs - (_t_).start.secs + 1; \
297 1.1 oster } \
298 1.1 oster }
299 1.1 oster
300 1.1 oster #define RF_ETIMER_VAL_US(_t_) (((_t_).elapsed.secs*RF_USEC_PER_SEC)+((_t_).elapsed.nsecs/1000))
301 1.1 oster #define RF_ETIMER_VAL_MS(_t_) (((_t_).elapsed.secs*RF_MSEC_PER_SEC)+((_t_).elapsed.nsecs/1000000))
302 1.1 oster
303 1.1 oster #endif /* _IBMR2 */
304 1.1 oster
305 1.1 oster /*
306 1.1 oster * XXX investigate better timing for these
307 1.1 oster */
308 1.1 oster #if defined(hpux) || defined(sun) || defined(NETBSD_I386) || defined(ultrix) || defined(LINUX_I386) || defined(IRIX) || (defined(MACH) && !defined(__osf__))
309 1.1 oster #include <sys/time.h>
310 1.1 oster
311 1.1 oster #define RF_USEC_PER_SEC 1000000
312 1.1 oster
313 1.1 oster struct RF_Etimer_s {
314 1.1 oster struct timeval start;
315 1.1 oster struct timeval end;
316 1.1 oster struct timeval elapsed;
317 1.1 oster };
318 1.1 oster #ifndef __NetBSD__
319 1.1 oster #define RF_ETIMER_START(_t_) { \
320 1.1 oster gettimeofday(&((_t_).start), NULL); \
321 1.1 oster }
322 1.1 oster
323 1.1 oster #define RF_ETIMER_STOP(_t_) { \
324 1.1 oster gettimeofday(&((_t_).end), NULL); \
325 1.1 oster }
326 1.1 oster
327 1.1 oster #else
328 1.1 oster #define RF_ETIMER_START(_t_) { \
329 1.1 oster }
330 1.1 oster /* XXX these just drop off the end of the world... */
331 1.1 oster #define RF_ETIMER_STOP(_t_) { \
332 1.1 oster }
333 1.1 oster #endif
334 1.1 oster
335 1.1 oster #define RF_ETIMER_EVAL(_t_) { \
336 1.1 oster if ((_t_).end.tv_usec >= (_t_).start.tv_usec) { \
337 1.1 oster (_t_).elapsed.tv_usec = (_t_).end.tv_usec - (_t_).start.tv_usec; \
338 1.1 oster (_t_).elapsed.tv_sec = (_t_).end.tv_sec - (_t_).start.tv_usec; \
339 1.1 oster } \
340 1.1 oster else { \
341 1.1 oster (_t_).elapsed.tv_usec = RF_USEC_PER_SEC + (_t_).end.tv_usec; \
342 1.1 oster (_t_).elapsed.tv_usec -= (_t_).start.tv_usec; \
343 1.1 oster (_t_).elapsed.tv_sec = (_t_).end.tv_sec - (_t_).start.tv_sec + 1; \
344 1.1 oster } \
345 1.1 oster }
346 1.1 oster
347 1.1 oster #define RF_ETIMER_VAL_US(_t_) (((_t_).elapsed.tv_sec*RF_USEC_PER_SEC)+(_t_).elapsed.tv_usec)
348 1.1 oster #define RF_ETIMER_VAL_MS(_t_) (((_t_).elapsed.tv_sec*RF_MSEC_PER_SEC)+((_t_).elapsed.tv_usec/1000))
349 1.1 oster
350 1.1 oster #endif /* hpux || sun || NETBSD_I386 || ultrix || LINUX_I386 || IRIX || (MACH && !__osf__) */
351 1.1 oster
352 1.1 oster #endif /* !_RF__RF_TIMER_H_ */
353