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