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