1 #ifndef CPUTIME_H
2 #define CPUTIME_H
3 
4 /*
5  * Figure out what clock to use.  Each possibility can be specifically
6  * enabled or disabled by predefining USE_XXX to 1 or 0.  For some,
7  * the code attempts to detect availability automatically.  If the
8  * Symbols HAVE_XXX are defined, they are used.  If not, they are
9  * set to reasonable default assumptions while further conditions
10  * are checked.  The choices, and the ways they are auto-detected are:
11  * - gethrvtime(), if HAVE_GETHRVTIME is set to 1.
12  * - clock_gettime(CLOCK_VIRTUAL,...), if CLOCK_VIRTUAL is defined in <time.h>
13  * - getrusage(RUSAGE_SELF,...), if RUSAGE_SELF is defined in <sys/resource.h>
14  * - clock(), if CLOCKS_PER_SEC or CLK_TCK are defined in <time.h>
15  * - time(), unless specifically disabled.
16  *
17  * The symbol CLOCK_AVAIL is given a value of 1 if a clock is found.
18  * The following are then available:
19  * timetype (typedef): the type needed to hold a clock value.
20  * gettime(t) (macro): A function that gets passed a timetype *.
21  * subtime(d,s) (macro): Sets d -= s, essentially.
22  * msec(t) (macro): Given a timetype, return the number of milliseconds
23  *	in it, as an unsigned integer between 0 and 999.
24  * sec(t) (macro): Given a timetype, return the number of seconds in it,
25  *	as an unsigned long integer.
26  */
27 
28 /* We expect that our caller has already #included "bnconfig.h" if possible. */
29 
30 #ifndef unix
31 #define unix 0
32 #endif
33 #ifndef __unix
34 #define __unix 0
35 #endif
36 #ifndef __unix__
37 #define __unix__ 0
38 #endif
39 
40 #ifdef UNIX
41 /* Nothing */
42 #elif unix
43 #define UNIX 1
44 #elif __unix
45 #define UNIX 1
46 #elif __unix__
47 #define UNIX 1
48 #endif
49 
50 #ifndef UNIX
51 #define UNIX 0
52 #endif
53 
54 #ifndef TIME_WITH_SYS_TIME
55 #define TIME_WITH_SYS_TIME 1	/* Assume true if not told */
56 #endif
57 #ifndef HAVE_SYS_TIME_H
58 #define HAVE_SYS_TIME_H 0	/* Assume true if not told */
59 #endif
60 
61 /*
62  * Include <time.h> unless that would prevent us from later including
63  * <sys/time.h>, in which case include *that* immediately.
64  */
65 #if TIME_WITH_SYS_TIME
66 #include <time.h>
67 #elif HAVE_SYS_TIME_H
68 #include <sys/time.h>
69 #else
70 #include <time.h>
71 #endif
72 
73 #ifndef USE_GETHRVTIME
74 #ifdef HAVE_GETHRVTIME
75 #define USE_GETHRVTIME HAVE_GETHRVTIME
76 #else
77 #define USE_GETHRVTIME 0
78 #endif
79 #endif
80 
81 #if USE_GETHRVTIME
82 #define CLOCK_AVAIL 1
83 typedef hrtime_t timetype;
84 #define gettime(t) *(t) = gethrvtime()
85 #define subtime(d,s) d -= s
86 #define msec(t) (unsigned)((t/1000000)%1000)
87 #define sec(t) (unsigned long)(t/1000000000)
88 
89 #else
90 #ifndef USE_CLOCK_GETTIME
91 #define USE_CLOCK_GETTIME 0
92 #ifndef HAVE_CLOCK_GETTIME
93 #define HAVE_CLOCK_GETTIME 1	/* Assume the CLOCK_VIRTUAL test will catch */
94 #endif
95 /*
96  * It turns out to be non-ANSI to use the apparently simpler construct
97  * "#define USE_CLOCK_GETTIME defined(CLOCK_VIRTUAL)", since
98  * "If the token defined is generated as a result of this replacement
99  *  process or use of the defined unary operator does not match one
100  *  of the two specified forms prior ro macro replacement, the behaviour
101  *  is undefined."  (ANSI/ISO 9899-1990 section 6.8.1)
102  * In practice, it breaks the DEC Alpha compiler.
103  */
104 #if HAVE_CLOCK_GETTIME
105 #ifdef CLOCK_VIRTUAL
106 #ifdef USE_CLOCK_GETTIME
107 #undef USE_CLOCK_GETTIME
108 #endif
109 #define USE_CLOCK_GETTIME 1
110 #endif
111 #endif
112 #endif
113 
114 #if USE_CLOCK_GETTIME
115 #define CLOCK_AVAIL 1
116 typedef struct timespec timetype;
117 #define gettime(t) clock_gettime(CLOCK_VIRTUAL, t)
118 #define subtime(d,s) \
119 	d.tv_sec -= s.tv_sec + (d.tv_nsec >= s.tv_nsec ? \
120 	                        (d.tv_nsec -= s.tv_nsec, 0) : \
121 	                        (d.tv_nsec += 1000000000-s.tv_nsec, 1))
122 #define msec(t) (unsigned)(t.tv_nsec/1000000)
123 #define sec(t) (unsigned long)(t.tv_sec)
124 
125 #else
126 #if UNIX
127 #ifndef HAVE_GETRUSAGE
128 #define HAVE_GETRUSAGE 1
129 #endif
130 #endif /* UNIX */
131 
132 #define USE_GETRUSAGE 0
133 
134 /* AJR */
135 /*#define HAVE_GETRUSAGE 0*/
136 
137 #include <sys/time.h>
138 #if HAVE_GETRUSAGE
139 #if TIME_WITH_SYS_TIME
140 #ifndef HAVE_SYS_TIME_H
141 #include <sys/time.h>
142 #elif HAVE_SYS_TIME_H
143 #include <sys/time.h>
144 #endif
145 #endif /* TIME_WITH_SYS_TIME */
146 #include <sys/resource.h>
147 
148 #ifdef RUSAGE_SELF
149 #undef USE_GETRUSAGE
150 #define USE_GETRUSAGE 1
151 #endif
152 #endif /* HAVE_GETRUSAGE */
153 
154 #if USE_GETRUSAGE
155 #define CLOCK_AVAIL 1
156 typedef struct rusage timetype;
157 #define gettime(t) getrusage(RUSAGE_SELF, t);
158 #define subtime(d, s) \
159 	d.ru_utime.tv_sec -= s.ru_utime.tv_sec + \
160 	             (d.ru_utime.tv_usec >= s.ru_utime.tv_usec ? \
161 	              (d.ru_utime.tv_usec -= s.ru_utime.tv_usec, 0) : \
162 	              (d.ru_utime.tv_usec += 1000000-s.ru_utime.tv_usec, 1))
163 #define msec(t) (unsigned)(t.ru_utime.tv_usec/1000)
164 #define sec(t) (unsigned long)(t.ru_utime.tv_sec)
165 
166 #else
167 
168 #ifndef HAVE_CLOCK
169 #define HAVE_CLOCK 1
170 #endif
171 
172 #define USE_CLOCK 0
173 #define USE_TIME 0
174 
175 #if HAVE_CLOCK
176 #ifndef CLOCKS_PER_SEC
177 #ifdef CLK_TCK
178 #define CLOCKS_PER_SEC CLK_TCK
179 #endif
180 #endif /* !defined(CLOCKS_PER_SEC) */
181 
182 #ifndef USE_CLOCK
183 #ifdef CLOCKS_PER_SEC
184 #define USE_CLOCK 1
185 #endif
186 #endif /* !defined(USE_CLOCK) */
187 #endif /* HAVE_CLOCK */
188 
189 #if USE_CLOCK
190 #define CLOCK_AVAIL 1
191 typedef clock_t timetype;
192 #define gettime(t) *(t) = clock()
193 #define subtime(d, s) d -= s
194 /*
195  * I don't like having to do floating point math.  CLOCKS_PER_SEC is
196  * almost always an integer, and the most common non-integral case is
197  * the MS-DOS wierdness of 18.2.  We have to be a bit careful with the
198  * casts, because ANSI C doesn't provide % with non-integral operands,
199  * but just to be extra annoying, some implementations define it as an
200  * integral-valued float.  (E.g. Borland C++ 4.5 with 1000.0)
201  */
202 /* AJR  #if ((unsigned)CLOCKS_PER_SEC == CLOCKS_PER_SEC)*/
203 #if 1
204 	/* Integer CLOCKS_PER_SEC */
205 
206 #define sec(t) (unsigned long)(t/CLOCKS_PER_SEC)
207 #define msec(t) (unsigned)(t % (unsigned)CLOCKS_PER_SEC * 1000 / \
208 					(unsigned)CLOCKS_PER_SEC)
209 /* AJR  #elif (CLOCKS_PER_SEC == 18.2)*/
210 #elif 0
211 	/* MS-DOS-ism */
212 
213 #define sec(t) (unsigned long)(t*5 / 91)
214 #define msec(t) (unsigned)(t*5 % 91 * 1000 / 91)
215 
216 #else /* We are forced to muck with floating point.... */
217 
218 #include <math.h>	/* For floor() */
219 #define sec(t) (unsigned long)(t/CLOCKS_PER_SEC)
220 #define msec(t) (unsigned)((t - sec(t)*CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC)
221 
222 #endif
223 
224 #else
225 
226 #ifndef HAVE_TIME
227 #define HAVE_TIME 1
228 #endif
229 
230 #if HAVE_TIME
231 #ifndef USE_TIME
232 #define USE_TIME 1
233 #endif
234 #endif
235 
236 #if USE_TIME
237 #define CLOCK_AVAIL 1
238 typedef time_t timetype;
239 #define gettime(t) time(t)
240 #define subtime(d, s) d -= s
241 #define msec(t) (unsigned)0
242 #define sec(t) (unsigned long)t
243 
244 #endif /* USE_TIME */
245 #endif /* USE_CLOCK */
246 #endif /* USE_GETRUSAGE */
247 #endif /* USE_CLOCK_GETTIME */
248 #endif /* USE_GETHRVTIME */
249 
250 #endif /*CPUTIME_H*/
251