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