ulps: Fix long lines
[mathlib.git] / etc / proffenv.c
CommitLineData
d0213500 1#include <assert.h>
2#include <fenv.h>
3#include <stdio.h>
d0213500 4#include <time.h>
5#include <sys/time.h>
6
7/* Function prototypes */
8a5c9a9e 8static int prof_clearexcept_all(size_t iterations);
9static int prof_clearexcept_random(size_t iterations);
10static int prof_getenv(size_t iterations);
19258048 11static int prof_getround(size_t iterations);
22d17f71 12static int prof_holdexcept(size_t iterations);
16ffbff5 13static int prof_raiseexcept(size_t iterations);
8a5c9a9e 14static int prof_setenv_default(size_t iterations);
8a5c9a9e 15static int prof_setenv_getenv(size_t iterations);
19258048 16static int prof_setround(size_t iterations);
16ffbff5 17static int prof_updateenv_default(size_t iterations);
8a5c9a9e 18static int prof_updateenv_getenv(size_t iterations);
d0213500 19
16ffbff5 20
24e891a5 21/* Constants and macros */
19258048 22#define ITERATIONS (10 * 1000 * 1000)
d0213500 23
48288bbc 24/*
25 * They are esentially the same, but we still define them as if
26 * they were different, for conceptual consistency and clarity.
27 */
24e891a5 28#define MARK_START(tv1) \
29 assert(gettimeofday(tv1, NULL) == 0);
30
31#define MARK_END(tv2) \
32 assert(gettimeofday(tv2, NULL) == 0);
33
34#define MSECS(tv1, tv2) \
35 (((tv2).tv_sec - (tv1).tv_sec ) * 1000 + \
36 ((tv2).tv_usec - (tv1).tv_usec) / 1000)
37
48e5dc4e 38static int extable[] = {
39#ifdef FE_DIVBYZERO
40 FE_DIVBYZERO,
41#endif
42#ifdef FE_INEXACT
43 FE_INEXACT,
44#endif
45#ifdef FE_INVALID
46 FE_INVALID,
47#endif
48#ifdef FE_OVERFLOW
49 FE_OVERFLOW,
50#endif
51#ifdef FE_UNDERFLOW
52 FE_UNDERFLOW,
53#endif
54#ifdef FE_ALL_EXCEPT
55 FE_ALL_EXCEPT
56#endif
57};
58
16ffbff5 59struct pentry {
60 const char *p_desc;
61 int (*p_func)();
62 size_t p_iter;
63} ptable[] = {
64 { "feclearexcept() FE_ALL_EXCEPT",
65 prof_clearexcept_all,
66 ITERATIONS },
67
68 { "feclearexcept() random",
69 prof_clearexcept_random,
70 ITERATIONS },
71
72 { " fegetenv() ",
73 prof_getenv,
74 ITERATIONS },
75
19258048
SK
76 { " fegetround() ",
77 prof_getround,
78 ITERATIONS },
79
22d17f71
SK
80 { " feholdexcept() ",
81 prof_holdexcept,
82 ITERATIONS },
83
19258048
SK
84 { "feraiseexcept() ",
85 prof_raiseexcept,
86 ITERATIONS },
16ffbff5 87
88 { " fesetenv() FE_DFL_ENV",
89 prof_setenv_default,
90 ITERATIONS },
91
92 { " fesetenv() random",
93 prof_setenv_getenv,
94 ITERATIONS },
95
19258048
SK
96 { " fesetround() ",
97 prof_setround,
98 ITERATIONS },
99
16ffbff5 100 { " feupdateenv() FE_DFL_ENV",
101 prof_updateenv_default,
102 ITERATIONS },
103
104 { " feupdateenv() random",
105 prof_updateenv_getenv,
106 ITERATIONS },
107
108 { NULL, NULL, 0 }
109};
110
d0213500 111int
112main(void)
113{
16ffbff5 114 const struct pentry *p;
d0213500 115 int msecs;
116
16ffbff5 117 for (p = ptable; p; p++) {
118 if (p->p_desc == NULL && p->p_func == NULL && p->p_iter == 0)
119 break;
120
121 msecs = p->p_func(p->p_iter);
122 printf("%s: %5d msecs for %d iterations\n",
123 p->p_desc, msecs, p->p_iter);
124 }
d0213500 125
126 return 0;
127}
128
129static int
8a5c9a9e 130prof_clearexcept_all(size_t iterations)
edbb7e04 131{
132 struct timeval tv1, tv2;
16ffbff5 133 size_t i;
edbb7e04 134
135 MARK_START(&tv1);
136
137 for (i = 0; i < iterations; i++)
138 assert(feclearexcept(FE_ALL_EXCEPT) == 0);
139
140 MARK_END(&tv2);
141
142 return MSECS(tv1, tv2);
143}
144
145static int
8a5c9a9e 146prof_clearexcept_random(size_t iterations)
48e5dc4e 147{
edbb7e04 148 struct timeval tv1, tv2;
edbb7e04 149 size_t i, N;
48e5dc4e 150
48e5dc4e 151 N = sizeof(extable) / sizeof(extable[0]);
152 assert(N != 0);
153
8a5c9a9e 154 MARK_START(&tv1);
155
edbb7e04 156 for (i = 0; i < iterations; i++)
157 assert(feclearexcept(extable[i%N]) == 0);
48e5dc4e 158
edbb7e04 159 MARK_END(&tv2);
48e5dc4e 160
edbb7e04 161 return MSECS(tv1, tv2);
48e5dc4e 162}
163
164static int
8a5c9a9e 165prof_getenv(size_t iterations)
d0213500 166{
167 struct timeval tv1, tv2;
24e891a5 168 fenv_t env;
169 size_t i;
170
171 MARK_START(&tv1);
172
173 for (i = 0; i < iterations; i++)
174 assert(fegetenv(&env) == 0);
d0213500 175
24e891a5 176 MARK_END(&tv2);
177
178 return MSECS(tv1, tv2);
179}
180
181static int
19258048
SK
182prof_getround(size_t iterations)
183{
184 struct timeval tv1, tv2;
185 size_t i;
186
187 MARK_START(&tv1);
188
189 for (i = 0; i < iterations; i++)
190 assert(fegetround() == 0);
191
192 MARK_END(&tv2);
193
194 return MSECS(tv1, tv2);
195}
196
197static int
22d17f71
SK
198prof_holdexcept(size_t iterations)
199{
200 struct timeval tv1, tv2;
201 fenv_t env;
202 size_t i;
203
204 MARK_START(&tv1);
205
206 for (i = 0; i < iterations; i++)
207 assert(feholdexcept(&env) == 0);
208
209 MARK_END(&tv2);
210
211 return MSECS(tv1, tv2);
212}
213
214static int
8a5c9a9e 215prof_setenv_default(size_t iterations)
24e891a5 216{
217 struct timeval tv1, tv2;
218 size_t i;
d0213500 219
24e891a5 220 MARK_START(&tv1);
d0213500 221
24e891a5 222 for (i = 0; i < iterations; i++)
223 assert(fesetenv(FE_DFL_ENV) == 0);
d0213500 224
24e891a5 225 MARK_END(&tv2);
d0213500 226
24e891a5 227 return MSECS(tv1, tv2);
d0213500 228}
229
230static int
16ffbff5 231prof_updateenv_default(size_t iterations)
d0213500 232{
233 struct timeval tv1, tv2;
24e891a5 234 size_t i;
24e891a5 235
236 MARK_START(&tv1);
237
238 for (i = 0; i < iterations; i++)
239 assert(feupdateenv(FE_DFL_ENV) == 0);
240
241 MARK_END(&tv2);
d0213500 242
24e891a5 243 return MSECS(tv1, tv2);
244}
245
246static int
8a5c9a9e 247prof_setenv_getenv(size_t iterations)
24e891a5 248{
249 struct timeval tv1, tv2;
250 fenv_t env;
251 size_t i;
252
253 MARK_START(&tv1);
254
255 for (i = 0; i < iterations; i++) {
256 assert(fegetenv(&env) == 0);
257 assert(fesetenv(&env) == 0);
258 }
259
260 MARK_END(&tv2);
261
262 return MSECS(tv1, tv2);
263}
264
265static int
19258048
SK
266prof_setround(size_t iterations)
267{
268 const int rndmodes[] = {
269#ifdef FE_DOWNWARD
270 FE_DOWNWARD,
271#endif
272#ifdef FE_TONEAREST
273 FE_TONEAREST,
274#endif
275#ifdef FE_TOWARDZERO
276 FE_TOWARDZERO,
277#endif
278#ifdef FE_UPWARD
279 FE_UPWARD
280#endif
281 };
282 const size_t N = sizeof(rndmodes) / sizeof(rndmodes[0]);
283 struct timeval tv1, tv2;
284 size_t i;
285
286 MARK_START(&tv1);
287
288 for (i = 0; i < iterations; i++) {
289 assert(fesetround(rndmodes[i % N]) == 0);
290 }
291
292 MARK_END(&tv2);
293
294 return MSECS(tv1, tv2);
295}
296
297static int
8a5c9a9e 298prof_updateenv_getenv(size_t iterations)
24e891a5 299{
300 struct timeval tv1, tv2;
301 fenv_t env;
302 size_t i;
d0213500 303
24e891a5 304 MARK_START(&tv1);
d0213500 305
24e891a5 306 for (i = 0; i < iterations; i++) {
307 assert(fegetenv(&env) == 0);
308 assert(feupdateenv(&env) == 0);
309 }
d0213500 310
24e891a5 311 MARK_END(&tv2);
d0213500 312
24e891a5 313 return MSECS(tv1, tv2);
d0213500 314}
16ffbff5 315
316static int
317prof_raiseexcept(size_t iterations)
318{
319 struct timeval tv1, tv2;
320 size_t i, N;
321
322 N = sizeof(extable) / sizeof(extable[0]);
323 assert(N > 0);
324
325 MARK_START(&tv1);
326
327 for (i = 0; i < iterations; i++) {
328 assert(feraiseexcept(extable[i%N]) == 0);
329 }
330
331 MARK_END(&tv2);
332
333 return MSECS(tv1, tv2);
334}