1 /*
2  * Copyright (C) 2013-2021 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * This code is a complete clean re-write of the stress tool by
19  * Colin Ian King <colin.king@canonical.com> and attempts to be
20  * backwardly compatible with the stress tool by Amos Waterland
21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
22  * functionality.
23  *
24  */
25 #include "stress-ng.h"
26 
27 typedef void (*stress_funccall_func)(const stress_args_t *argse);
28 
29 typedef struct {
30 	const char              *name;  /* human readable form of stressor */
31 	const stress_funccall_func   func;   /* the funccall method function */
32 } stress_funccall_method_info_t;
33 
34 static const stress_funccall_method_info_t funccall_methods[];
35 
36 static const stress_help_t help[] = {
37 	{ NULL,	"funccall N",		"start N workers exercising 1 to 9 arg functions" },
38 	{ NULL,	"funccall-ops N",	"stop after N function call bogo operations" },
39 	{ NULL,	"funccall-method M",	"select function call method M" },
40 	{ NULL,	NULL,			NULL }
41 };
42 
43 #define bool_put	stress_uint8_put
44 #define uint8_t_put	stress_uint8_put
45 #define uint16_t_put	stress_uint16_put
46 #define uint32_t_put	stress_uint32_put
47 #define uint64_t_put	stress_uint64_put
48 #define __uint128_t_put	stress_uint128_put
49 #define float_put	stress_float_put
50 #define double_put	stress_double_put
51 #define stress_long_double_t_put stress_long_double_put
52 typedef long double 		stress_long_double_t;
53 #if defined(HAVE_COMPLEX_H) &&			\
54     defined(HAVE_COMPLEX) &&			\
55     defined(__STDC_IEC_559_COMPLEX__) &&	\
56     !defined(__UCLIBC__)
57 #define stress_complex_float_t_put stress_complex_put
58 #define stress_complex_double_t_put stress_complex_put
59 #define stress_complex_long_double_t_put stress_complex_put
60 typedef complex float		stress_complex_float_t;
61 typedef complex double		stress_complex_double_t;
62 typedef complex long double	stress_complex_long_double_t;
63 #endif
64 
stress_mwcfloat(void)65 static inline float stress_mwcfloat(void)
66 {
67 	const uint32_t r = stress_mwc32();
68 
69 	return (float)r / (float)(0xffffffffUL);
70 }
71 
stress_mwcdouble(void)72 static inline double stress_mwcdouble(void)
73 {
74 	const uint64_t r = stress_mwc64();
75 
76 	return (double)r / (double)(0xffffffffffffffffULL);
77 }
78 
79 #define stress_funccall_type(type, rndfunc)				\
80 static void NOINLINE stress_funccall_ ## type(const stress_args_t *args);	\
81 									\
82 static void NOINLINE stress_funccall_ ## type(const stress_args_t *args)	\
83 {									\
84 	register int ii;						\
85 	type a, b, c, d, e, f, g, h, i;					\
86 									\
87 	a = rndfunc();							\
88 	b = rndfunc();							\
89 	c = rndfunc();							\
90 	d = rndfunc();							\
91 	e = rndfunc();							\
92 	f = rndfunc();							\
93 	g = rndfunc();							\
94 	h = rndfunc();							\
95 	i = rndfunc();							\
96 									\
97 	do {								\
98 		for (ii = 0; ii < 1000; ii++) {				\
99 			type res = 					\
100 			(stress_funccall_ ## type ## _1(a) + 		\
101 			 stress_funccall_ ## type ## _2(a, b) +		\
102 			 stress_funccall_ ## type ## _3(a, b,		\
103 				c) +					\
104 			 stress_funccall_ ## type ## _4(a, b, 		\
105 				c, d) + 				\
106 			 stress_funccall_ ## type ## _5(a, b,		\
107 				c, d, e) +				\
108 			 stress_funccall_ ## type ## _6(a, b,		\
109 				c, d, e, f) + 				\
110 			 stress_funccall_ ## type ## _7(a, b,		\
111 				c, d, e, f, g) + 			\
112 			 stress_funccall_ ## type ## _8(a, b,		\
113 				c, d, e, f, g, h) + 			\
114 			 stress_funccall_ ## type ## _9(a, b,		\
115 				c, d, e, f, g, h, i));			\
116 									\
117 			res += 						\
118 			(stress_funcdeep_ ## type ## _2(a, b) +		\
119 			 stress_funcdeep_ ## type ## _3(a, b,		\
120 				c) + 					\
121 			 stress_funcdeep_ ## type ## _4(a, b, 		\
122 				c, d) +					\
123 			 stress_funcdeep_ ## type ## _5(a, b,		\
124 				c, d, e) +				\
125 			 stress_funcdeep_ ## type ## _6(a, b,		\
126 				c, d, e, f) +				\
127 			 stress_funcdeep_ ## type ## _7(a, b,		\
128 				c, d, e, f, g) +			\
129 			 stress_funcdeep_ ## type ## _8(a, b,		\
130 				c, d, e, f, g, h) +			\
131 			 stress_funcdeep_ ## type ## _9(a, b,		\
132 				c, d, e, f, g, h, i));			\
133 			type ## _put(res);				\
134 			}						\
135 		inc_counter(args);					\
136 	} while (keep_stressing(args));					\
137 }
138 
139 #define stress_funccall_1(type)				\
140 static type NOINLINE stress_funccall_ ## type ## _1(	\
141 	const type a);					\
142 							\
143 static type NOINLINE stress_funccall_ ## type ## _1(	\
144 	const type a)					\
145 {							\
146 	type ## _put(a);				\
147 	return a;					\
148 }							\
149 
150 #define stress_funccall_2(type)				\
151 static type  NOINLINE stress_funccall_ ## type ## _2(	\
152 	const type a,					\
153 	const type b);					\
154 							\
155 static type NOINLINE stress_funccall_ ## type ## _2(	\
156 	const type a,					\
157 	const type b)					\
158 {							\
159 	type ## _put(a);				\
160 	type ## _put(b);				\
161 	return a + b;					\
162 }							\
163 
164 #define stress_funccall_3(type)				\
165 static type NOINLINE stress_funccall_ ## type ## _3(	\
166 	const type a,					\
167 	const type b,					\
168 	const type c);					\
169 							\
170 static type NOINLINE stress_funccall_ ## type ## _3(	\
171 	const type a,					\
172 	const type b,					\
173 	const type c)					\
174 {							\
175 	type ## _put(a);				\
176 	type ## _put(b);				\
177 	type ## _put(c);				\
178 	return a + b + c;				\
179 }							\
180 
181 #define stress_funccall_4(type)				\
182 static type NOINLINE stress_funccall_ ## type ## _4(	\
183 	const type a,					\
184 	const type b,					\
185 	const type c,					\
186 	const type d);					\
187 							\
188 static type NOINLINE stress_funccall_ ## type ## _4(	\
189 	const type a,					\
190 	const type b,					\
191 	const type c,					\
192 	const type d)					\
193 {							\
194 	type ## _put(a);				\
195 	type ## _put(b);				\
196 	type ## _put(c);				\
197 	type ## _put(d);				\
198 	return a + b + c + d;				\
199 }							\
200 
201 #define stress_funccall_5(type)				\
202 static type NOINLINE stress_funccall_ ## type ## _5(	\
203 	const type a,					\
204 	const type b,					\
205 	const type c,					\
206 	const type d,					\
207 	const type e);					\
208 							\
209 static type NOINLINE stress_funccall_ ## type ## _5(	\
210 	const type a,					\
211 	const type b,					\
212 	const type c,					\
213 	const type d,					\
214 	const type e)					\
215 {							\
216 	type ## _put(a);				\
217 	type ## _put(b);				\
218 	type ## _put(c);				\
219 	type ## _put(d);				\
220 	type ## _put(e);				\
221 	return a + b + c + d + e;			\
222 }							\
223 
224 #define stress_funccall_6(type)				\
225 static type NOINLINE stress_funccall_ ## type ## _6(	\
226 	const type a,					\
227 	const type b,					\
228 	const type c,					\
229 	const type d,					\
230 	const type e,					\
231 	const type f);					\
232 							\
233 static type NOINLINE stress_funccall_ ## type ## _6(	\
234 	const type a,					\
235 	const type b,					\
236 	const type c,					\
237 	const type d,					\
238 	const type e,					\
239 	const type f)					\
240 {							\
241 	type ## _put(a);				\
242 	type ## _put(b);				\
243 	type ## _put(c);				\
244 	type ## _put(d);				\
245 	type ## _put(e);				\
246 	type ## _put(f);				\
247 	return a + b + c + d + e + f;			\
248 }							\
249 
250 #define stress_funccall_7(type)				\
251 static type NOINLINE stress_funccall_ ## type ## _7(	\
252 	const type a,					\
253 	const type b,					\
254 	const type c,					\
255 	const type d,					\
256 	const type e,					\
257 	const type f,					\
258 	const type g);					\
259 							\
260 static type NOINLINE stress_funccall_ ## type ## _7(	\
261 	const type a,					\
262 	const type b,					\
263 	const type c,					\
264 	const type d,					\
265 	const type e,					\
266 	const type f,					\
267 	const type g)					\
268 {							\
269 	type ## _put(a);				\
270 	type ## _put(b);				\
271 	type ## _put(c);				\
272 	type ## _put(d);				\
273 	type ## _put(e);				\
274 	type ## _put(f);				\
275 	type ## _put(g);				\
276 	return a + b + c + d + e + f + g;		\
277 }							\
278 
279 #define stress_funccall_8(type)				\
280 static type NOINLINE stress_funccall_ ## type ## _8(	\
281 	const type a,					\
282 	const type b,					\
283 	const type c,					\
284 	const type d,					\
285 	const type e,					\
286 	const type f,					\
287 	const type g,					\
288 	const type h);					\
289 							\
290 static type NOINLINE stress_funccall_ ## type ## _8(	\
291 	const type a,					\
292 	const type b,					\
293 	const type c,					\
294 	const type d,					\
295 	const type e,					\
296 	const type f,					\
297 	const type g,					\
298 	const type h)					\
299 {							\
300 	type ## _put(a);				\
301 	type ## _put(b);				\
302 	type ## _put(c);				\
303 	type ## _put(d);				\
304 	type ## _put(e);				\
305 	type ## _put(f);				\
306 	type ## _put(g);				\
307 	type ## _put(h);				\
308 	return a + b + c + d + e + f + g + h;		\
309 }							\
310 
311 #define stress_funccall_9(type)				\
312 static type NOINLINE stress_funccall_ ## type ## _9(	\
313 	const type a,					\
314 	const type b,					\
315 	const type c,					\
316 	const type d,					\
317 	const type e,					\
318 	const type f,					\
319 	const type g,					\
320 	const type h,					\
321 	const type i);					\
322 							\
323 static type NOINLINE stress_funccall_ ## type ## _9(	\
324 	const type a,					\
325 	const type b,					\
326 	const type c,					\
327 	const type d,					\
328 	const type e,					\
329 	const type f,					\
330 	const type g,					\
331 	const type h,					\
332 	const type i)					\
333 {							\
334 	type ## _put(a);				\
335 	type ## _put(b);				\
336 	type ## _put(c);				\
337 	type ## _put(d);				\
338 	type ## _put(e);				\
339 	type ## _put(f);				\
340 	type ## _put(g);				\
341 	type ## _put(h);				\
342 	type ## _put(i);				\
343 	return a + b + c + d + e + f + g + h + i;	\
344 }							\
345 
346 #define stress_funcdeep_2(type)				\
347 static type NOINLINE stress_funcdeep_ ## type ## _2(	\
348 	const type a,					\
349 	const type b);					\
350 							\
351 static type NOINLINE stress_funcdeep_ ## type ## _2(	\
352 	const type a,					\
353 	const type b)					\
354 {							\
355 	return						\
356 	stress_funccall_ ## type ## _1(b) + 		\
357 	stress_funccall_ ## type ## _1(a);		\
358 }							\
359 
360 #define stress_funcdeep_3(type)				\
361 static type NOINLINE stress_funcdeep_ ## type ## _3(	\
362 	const type a,					\
363 	const type b,					\
364 	const type c);					\
365 							\
366 static type NOINLINE stress_funcdeep_ ## type ## _3(	\
367 	const type a,					\
368 	const type b,					\
369 	const type c)					\
370 {							\
371 	return						\
372 	stress_funcdeep_ ## type ## _2(c, b) +		\
373 	stress_funccall_ ## type ## _1(a);		\
374 }							\
375 
376 #define stress_funcdeep_4(type)				\
377 static type NOINLINE stress_funcdeep_ ## type ## _4(	\
378 	const type a,					\
379 	const type b,					\
380 	const type c,					\
381 	const type d);					\
382 							\
383 static type NOINLINE stress_funcdeep_ ## type ## _4(	\
384 	const type a,					\
385 	const type b,					\
386 	const type c,					\
387 	const type d)					\
388 {							\
389 	return						\
390 	stress_funcdeep_ ## type ## _3(d, c, b) + 	\
391 	stress_funccall_ ## type ## _1(a);		\
392 }							\
393 
394 #define stress_funcdeep_5(type)				\
395 static type NOINLINE stress_funcdeep_ ## type ## _5(	\
396 	const type a,					\
397 	const type b,					\
398 	const type c,					\
399 	const type d,					\
400 	const type e);					\
401 							\
402 static type NOINLINE stress_funcdeep_ ## type ## _5(	\
403 	const type a,					\
404 	const type b,					\
405 	const type c,					\
406 	const type d,					\
407 	const type e)					\
408 {							\
409 	return						\
410 	stress_funcdeep_ ## type ## _4(e, d, c, b) + 	\
411 	stress_funccall_ ## type ## _1(a);		\
412 }							\
413 
414 #define stress_funcdeep_6(type)				\
415 static type NOINLINE stress_funcdeep_ ## type ## _6(	\
416 	const type a,					\
417 	const type b,					\
418 	const type c,					\
419 	const type d,					\
420 	const type e,					\
421 	const type f);					\
422 							\
423 static type NOINLINE stress_funcdeep_ ## type ## _6(	\
424 	const type a,					\
425 	const type b,					\
426 	const type c,					\
427 	const type d,					\
428 	const type e,					\
429 	const type f)					\
430 {							\
431 	return						\
432 	stress_funcdeep_ ## type ## _5(f, e, d, c, b) + \
433 	stress_funccall_ ## type ## _1(a);		\
434 }							\
435 
436 #define stress_funcdeep_7(type)				\
437 static type NOINLINE stress_funcdeep_ ## type ## _7(	\
438 	const type a,					\
439 	const type b,					\
440 	const type c,					\
441 	const type d,					\
442 	const type e,					\
443 	const type f,					\
444 	const type g);					\
445 							\
446 static type NOINLINE stress_funcdeep_ ## type ## _7(	\
447 	const type a,					\
448 	const type b,					\
449 	const type c,					\
450 	const type d,					\
451 	const type e,					\
452 	const type f,					\
453 	const type g)					\
454 {							\
455 	return						\
456 	stress_funcdeep_ ## type ## _6(g, f, e, d, c, b) + \
457 	stress_funccall_ ## type ## _1(a);		\
458 }							\
459 
460 #define stress_funcdeep_8(type)				\
461 static type NOINLINE stress_funcdeep_ ## type ## _8(	\
462 	const type a,					\
463 	const type b,					\
464 	const type c,					\
465 	const type d,					\
466 	const type e,					\
467 	const type f,					\
468 	const type g,					\
469 	const type h);					\
470 							\
471 static type NOINLINE stress_funcdeep_ ## type ## _8(	\
472 	const type a,					\
473 	const type b,					\
474 	const type c,					\
475 	const type d,					\
476 	const type e,					\
477 	const type f,					\
478 	const type g,					\
479 	const type h)					\
480 {							\
481 	return						\
482 	stress_funcdeep_ ## type ## _7(h, g, f, e, d, c, b) + \
483 	stress_funccall_ ## type ## _1(a);		\
484 }							\
485 
486 #define stress_funcdeep_9(type)				\
487 static type NOINLINE stress_funcdeep_ ## type ## _9(	\
488 	const type a,					\
489 	const type b,					\
490 	const type c,					\
491 	const type d,					\
492 	const type e,					\
493 	const type f,					\
494 	const type g,					\
495 	const type h,					\
496 	const type i);					\
497 							\
498 static type NOINLINE stress_funcdeep_ ## type ## _9(	\
499 	const type a,					\
500 	const type b,					\
501 	const type c,					\
502 	const type d,					\
503 	const type e,					\
504 	const type f,					\
505 	const type g,					\
506 	const type h,					\
507 	const type i)					\
508 {							\
509 	return						\
510 	stress_funccall_ ## type ## _1(b) + 		\
511 	stress_funcdeep_ ## type ## _2(c, b) + 		\
512 	stress_funcdeep_ ## type ## _3(d, c, b) + 	\
513 	stress_funcdeep_ ## type ## _4(e, d, c, b) + 	\
514 	stress_funcdeep_ ## type ## _5(f, e, d, c, b) + \
515 	stress_funcdeep_ ## type ## _6(g, f, e, d, c, b) + \
516 	stress_funcdeep_ ## type ## _7(h, g, f, e, d, c, b) + \
517 	stress_funcdeep_ ## type ## _8(i, h, g, f, e, d, c, b) + \
518 	stress_funcdeep_ ## type ## _8(a, b, c, d, e, f, g, h) + \
519 	stress_funcdeep_ ## type ## _7(b, c, d, e, f, g, h) + \
520 	stress_funcdeep_ ## type ## _6(c, d, e, f, g, h) + \
521 	stress_funcdeep_ ## type ## _5(d, e, f, g, h) + \
522 	stress_funcdeep_ ## type ## _4(e, f, g, h) + 	\
523 	stress_funcdeep_ ## type ## _3(f, g, h) + 	\
524 	stress_funcdeep_ ## type ## _2(g, h) +		\
525 	stress_funccall_ ## type ## _1(h);		\
526 }							\
527 
528 stress_funccall_1(bool)
stress_funccall_2(bool)529 stress_funccall_2(bool)
530 stress_funccall_3(bool)
531 stress_funccall_4(bool)
532 stress_funccall_5(bool)
533 stress_funccall_6(bool)
534 stress_funccall_7(bool)
535 stress_funccall_8(bool)
536 stress_funccall_9(bool)
537 stress_funcdeep_2(bool)
538 stress_funcdeep_3(bool)
539 stress_funcdeep_4(bool)
540 stress_funcdeep_5(bool)
541 stress_funcdeep_6(bool)
542 stress_funcdeep_7(bool)
543 stress_funcdeep_8(bool)
544 stress_funcdeep_9(bool)
545 stress_funccall_type(bool, stress_mwc1)
546 
547 stress_funccall_1(uint8_t)
548 stress_funccall_2(uint8_t)
549 stress_funccall_3(uint8_t)
550 stress_funccall_4(uint8_t)
551 stress_funccall_5(uint8_t)
552 stress_funccall_6(uint8_t)
553 stress_funccall_7(uint8_t)
554 stress_funccall_8(uint8_t)
555 stress_funccall_9(uint8_t)
556 stress_funcdeep_2(uint8_t)
557 stress_funcdeep_3(uint8_t)
558 stress_funcdeep_4(uint8_t)
559 stress_funcdeep_5(uint8_t)
560 stress_funcdeep_6(uint8_t)
561 stress_funcdeep_7(uint8_t)
562 stress_funcdeep_8(uint8_t)
563 stress_funcdeep_9(uint8_t)
564 stress_funccall_type(uint8_t, stress_mwc8)
565 
566 stress_funccall_1(uint16_t)
567 stress_funccall_2(uint16_t)
568 stress_funccall_3(uint16_t)
569 stress_funccall_4(uint16_t)
570 stress_funccall_5(uint16_t)
571 stress_funccall_6(uint16_t)
572 stress_funccall_7(uint16_t)
573 stress_funccall_8(uint16_t)
574 stress_funccall_9(uint16_t)
575 stress_funcdeep_2(uint16_t)
576 stress_funcdeep_3(uint16_t)
577 stress_funcdeep_4(uint16_t)
578 stress_funcdeep_5(uint16_t)
579 stress_funcdeep_6(uint16_t)
580 stress_funcdeep_7(uint16_t)
581 stress_funcdeep_8(uint16_t)
582 stress_funcdeep_9(uint16_t)
583 stress_funccall_type(uint16_t, stress_mwc16)
584 
585 stress_funccall_1(uint32_t)
586 stress_funccall_2(uint32_t)
587 stress_funccall_3(uint32_t)
588 stress_funccall_4(uint32_t)
589 stress_funccall_5(uint32_t)
590 stress_funccall_6(uint32_t)
591 stress_funccall_7(uint32_t)
592 stress_funccall_8(uint32_t)
593 stress_funccall_9(uint32_t)
594 stress_funcdeep_2(uint32_t)
595 stress_funcdeep_3(uint32_t)
596 stress_funcdeep_4(uint32_t)
597 stress_funcdeep_5(uint32_t)
598 stress_funcdeep_6(uint32_t)
599 stress_funcdeep_7(uint32_t)
600 stress_funcdeep_8(uint32_t)
601 stress_funcdeep_9(uint32_t)
602 stress_funccall_type(uint32_t, stress_mwc32)
603 
604 stress_funccall_1(uint64_t)
605 stress_funccall_2(uint64_t)
606 stress_funccall_3(uint64_t)
607 stress_funccall_4(uint64_t)
608 stress_funccall_5(uint64_t)
609 stress_funccall_6(uint64_t)
610 stress_funccall_7(uint64_t)
611 stress_funccall_8(uint64_t)
612 stress_funccall_9(uint64_t)
613 stress_funcdeep_2(uint64_t)
614 stress_funcdeep_3(uint64_t)
615 stress_funcdeep_4(uint64_t)
616 stress_funcdeep_5(uint64_t)
617 stress_funcdeep_6(uint64_t)
618 stress_funcdeep_7(uint64_t)
619 stress_funcdeep_8(uint64_t)
620 stress_funcdeep_9(uint64_t)
621 stress_funccall_type(uint64_t, stress_mwc64)
622 
623 #if defined(HAVE_INT128_T)
624 stress_funccall_1(__uint128_t)
625 stress_funccall_2(__uint128_t)
626 stress_funccall_3(__uint128_t)
627 stress_funccall_4(__uint128_t)
628 stress_funccall_5(__uint128_t)
629 stress_funccall_6(__uint128_t)
630 stress_funccall_7(__uint128_t)
631 stress_funccall_8(__uint128_t)
632 stress_funccall_9(__uint128_t)
633 stress_funcdeep_2(__uint128_t)
634 stress_funcdeep_3(__uint128_t)
635 stress_funcdeep_4(__uint128_t)
636 stress_funcdeep_5(__uint128_t)
637 stress_funcdeep_6(__uint128_t)
638 stress_funcdeep_7(__uint128_t)
639 stress_funcdeep_8(__uint128_t)
640 stress_funcdeep_9(__uint128_t)
641 stress_funccall_type(__uint128_t, stress_mwc64)
642 #endif
643 
644 stress_funccall_1(float)
645 stress_funccall_2(float)
646 stress_funccall_3(float)
647 stress_funccall_4(float)
648 stress_funccall_5(float)
649 stress_funccall_6(float)
650 stress_funccall_7(float)
651 stress_funccall_8(float)
652 stress_funccall_9(float)
653 stress_funcdeep_2(float)
654 stress_funcdeep_3(float)
655 stress_funcdeep_4(float)
656 stress_funcdeep_5(float)
657 stress_funcdeep_6(float)
658 stress_funcdeep_7(float)
659 stress_funcdeep_8(float)
660 stress_funcdeep_9(float)
661 stress_funccall_type(float, stress_mwcfloat)
662 
663 stress_funccall_1(double)
664 stress_funccall_2(double)
665 stress_funccall_3(double)
666 stress_funccall_4(double)
667 stress_funccall_5(double)
668 stress_funccall_6(double)
669 stress_funccall_7(double)
670 stress_funccall_8(double)
671 stress_funccall_9(double)
672 stress_funcdeep_2(double)
673 stress_funcdeep_3(double)
674 stress_funcdeep_4(double)
675 stress_funcdeep_5(double)
676 stress_funcdeep_6(double)
677 stress_funcdeep_7(double)
678 stress_funcdeep_8(double)
679 stress_funcdeep_9(double)
680 stress_funccall_type(double, stress_mwcdouble)
681 
682 stress_funccall_1(stress_long_double_t)
683 stress_funccall_2(stress_long_double_t)
684 stress_funccall_3(stress_long_double_t)
685 stress_funccall_4(stress_long_double_t)
686 stress_funccall_5(stress_long_double_t)
687 stress_funccall_6(stress_long_double_t)
688 stress_funccall_7(stress_long_double_t)
689 stress_funccall_8(stress_long_double_t)
690 stress_funccall_9(stress_long_double_t)
691 stress_funcdeep_2(stress_long_double_t)
692 stress_funcdeep_3(stress_long_double_t)
693 stress_funcdeep_4(stress_long_double_t)
694 stress_funcdeep_5(stress_long_double_t)
695 stress_funcdeep_6(stress_long_double_t)
696 stress_funcdeep_7(stress_long_double_t)
697 stress_funcdeep_8(stress_long_double_t)
698 stress_funcdeep_9(stress_long_double_t)
699 stress_funccall_type(stress_long_double_t, stress_mwc64)
700 
701 #if defined(HAVE_COMPLEX_H) &&			\
702     defined(HAVE_COMPLEX) &&			\
703     defined(__STDC_IEC_559_COMPLEX__) &&	\
704     !defined(__UCLIBC__)
705 static inline void ALWAYS_INLINE stress_complex_put(const complex double a)
706 {
707 #if defined(HAVE_CREAL) &&	\
708     defined(HAVE_CIMAG)
709 	g_put_val.double_val = creal(a) * cimag(a);
710 #else
711 	g_put_val.double_val = a * a;
712 #endif
713 }
714 
715 stress_funccall_1(stress_complex_float_t)
stress_funccall_2(stress_complex_float_t)716 stress_funccall_2(stress_complex_float_t)
717 stress_funccall_3(stress_complex_float_t)
718 stress_funccall_4(stress_complex_float_t)
719 stress_funccall_5(stress_complex_float_t)
720 stress_funccall_6(stress_complex_float_t)
721 stress_funccall_7(stress_complex_float_t)
722 stress_funccall_8(stress_complex_float_t)
723 stress_funccall_9(stress_complex_float_t)
724 stress_funcdeep_2(stress_complex_float_t)
725 stress_funcdeep_3(stress_complex_float_t)
726 stress_funcdeep_4(stress_complex_float_t)
727 stress_funcdeep_5(stress_complex_float_t)
728 stress_funcdeep_6(stress_complex_float_t)
729 stress_funcdeep_7(stress_complex_float_t)
730 stress_funcdeep_8(stress_complex_float_t)
731 stress_funcdeep_9(stress_complex_float_t)
732 stress_funccall_type(stress_complex_float_t, stress_mwcdouble)
733 
734 stress_funccall_1(stress_complex_double_t)
735 stress_funccall_2(stress_complex_double_t)
736 stress_funccall_3(stress_complex_double_t)
737 stress_funccall_4(stress_complex_double_t)
738 stress_funccall_5(stress_complex_double_t)
739 stress_funccall_6(stress_complex_double_t)
740 stress_funccall_7(stress_complex_double_t)
741 stress_funccall_8(stress_complex_double_t)
742 stress_funccall_9(stress_complex_double_t)
743 stress_funcdeep_2(stress_complex_double_t)
744 stress_funcdeep_3(stress_complex_double_t)
745 stress_funcdeep_4(stress_complex_double_t)
746 stress_funcdeep_5(stress_complex_double_t)
747 stress_funcdeep_6(stress_complex_double_t)
748 stress_funcdeep_7(stress_complex_double_t)
749 stress_funcdeep_8(stress_complex_double_t)
750 stress_funcdeep_9(stress_complex_double_t)
751 stress_funccall_type(stress_complex_double_t, stress_mwcdouble)
752 
753 stress_funccall_1(stress_complex_long_double_t)
754 stress_funccall_2(stress_complex_long_double_t)
755 stress_funccall_3(stress_complex_long_double_t)
756 stress_funccall_4(stress_complex_long_double_t)
757 stress_funccall_5(stress_complex_long_double_t)
758 stress_funccall_6(stress_complex_long_double_t)
759 stress_funccall_7(stress_complex_long_double_t)
760 stress_funccall_8(stress_complex_long_double_t)
761 stress_funccall_9(stress_complex_long_double_t)
762 stress_funcdeep_2(stress_complex_long_double_t)
763 stress_funcdeep_3(stress_complex_long_double_t)
764 stress_funcdeep_4(stress_complex_long_double_t)
765 stress_funcdeep_5(stress_complex_long_double_t)
766 stress_funcdeep_6(stress_complex_long_double_t)
767 stress_funcdeep_7(stress_complex_long_double_t)
768 stress_funcdeep_8(stress_complex_long_double_t)
769 stress_funcdeep_9(stress_complex_long_double_t)
770 stress_funccall_type(stress_complex_long_double_t, stress_mwcdouble)
771 #endif
772 
773 /*
774  *  The PCC compiler complains at ALWAYS_INLINE, so disable it
775  */
776 #if defined(__PCC__)
777 #undef ALWAYS_INLINE
778 #define ALWAYS_INLINE
779 #endif
780 
781 #if defined(HAVE_FLOAT_DECIMAL32) &&	\
782     !defined(__clang__)
783 static inline void ALWAYS_INLINE _Decimal32_put(const _Decimal32 a)
784 {
785 	g_put_val.double_val = (double)a;
786 }
787 
788 stress_funccall_1(_Decimal32)
stress_funccall_2(_Decimal32)789 stress_funccall_2(_Decimal32)
790 stress_funccall_3(_Decimal32)
791 stress_funccall_4(_Decimal32)
792 stress_funccall_5(_Decimal32)
793 stress_funccall_6(_Decimal32)
794 stress_funccall_7(_Decimal32)
795 stress_funccall_8(_Decimal32)
796 stress_funccall_9(_Decimal32)
797 stress_funcdeep_2(_Decimal32)
798 stress_funcdeep_3(_Decimal32)
799 stress_funcdeep_4(_Decimal32)
800 stress_funcdeep_5(_Decimal32)
801 stress_funcdeep_6(_Decimal32)
802 stress_funcdeep_7(_Decimal32)
803 stress_funcdeep_8(_Decimal32)
804 stress_funcdeep_9(_Decimal32)
805 stress_funccall_type(_Decimal32, (_Decimal32)stress_mwc64)
806 #endif
807 
808 #if defined(HAVE_FLOAT_DECIMAL64) &&	\
809     !defined(__clang__)
810 static inline void ALWAYS_INLINE _Decimal64_put(const _Decimal64 a)
811 {
812 	g_put_val.double_val = (double)a;
813 }
814 
815 stress_funccall_1(_Decimal64)
stress_funccall_2(_Decimal64)816 stress_funccall_2(_Decimal64)
817 stress_funccall_3(_Decimal64)
818 stress_funccall_4(_Decimal64)
819 stress_funccall_5(_Decimal64)
820 stress_funccall_6(_Decimal64)
821 stress_funccall_7(_Decimal64)
822 stress_funccall_8(_Decimal64)
823 stress_funccall_9(_Decimal64)
824 stress_funcdeep_2(_Decimal64)
825 stress_funcdeep_3(_Decimal64)
826 stress_funcdeep_4(_Decimal64)
827 stress_funcdeep_5(_Decimal64)
828 stress_funcdeep_6(_Decimal64)
829 stress_funcdeep_7(_Decimal64)
830 stress_funcdeep_8(_Decimal64)
831 stress_funcdeep_9(_Decimal64)
832 stress_funccall_type(_Decimal64, (_Decimal64)stress_mwc64)
833 #endif
834 
835 #if defined(HAVE_FLOAT_DECIMAL128) &&	\
836     !defined(__clang__)
837 static inline void ALWAYS_INLINE _Decimal128_put(const _Decimal128 a)
838 {
839 	g_put_val.double_val = (double)a;
840 }
841 
842 stress_funccall_1(_Decimal128)
stress_funccall_2(_Decimal128)843 stress_funccall_2(_Decimal128)
844 stress_funccall_3(_Decimal128)
845 stress_funccall_4(_Decimal128)
846 stress_funccall_5(_Decimal128)
847 stress_funccall_6(_Decimal128)
848 stress_funccall_7(_Decimal128)
849 stress_funccall_8(_Decimal128)
850 stress_funccall_9(_Decimal128)
851 stress_funcdeep_2(_Decimal128)
852 stress_funcdeep_3(_Decimal128)
853 stress_funcdeep_4(_Decimal128)
854 stress_funcdeep_5(_Decimal128)
855 stress_funcdeep_6(_Decimal128)
856 stress_funcdeep_7(_Decimal128)
857 stress_funcdeep_8(_Decimal128)
858 stress_funcdeep_9(_Decimal128)
859 stress_funccall_type(_Decimal128, (_Decimal128)stress_mwc64)
860 #endif
861 
862 #if defined(HAVE_FLOAT16) &&	\
863     !defined(__clang__)
864 static inline void ALWAYS_INLINE __fp16_put(const __fp16 a)
865 {
866 	g_put_val.float_val = (float)a;
867 }
868 
869 stress_funccall_1(__fp16)
stress_funccall_2(__fp16)870 stress_funccall_2(__fp16)
871 stress_funccall_3(__fp16)
872 stress_funccall_4(__fp16)
873 stress_funccall_5(__fp16)
874 stress_funccall_6(__fp16)
875 stress_funccall_7(__fp16)
876 stress_funccall_8(__fp16)
877 stress_funccall_9(__fp16)
878 stress_funcdeep_2(__fp16)
879 stress_funcdeep_3(__fp16)
880 stress_funcdeep_4(__fp16)
881 stress_funcdeep_5(__fp16)
882 stress_funcdeep_6(__fp16)
883 stress_funcdeep_7(__fp16)
884 stress_funcdeep_8(__fp16)
885 stress_funcdeep_9(__fp16)
886 stress_funccall_type(__fp16, (__fp16)stress_mwc32)
887 #endif
888 
889 #if defined(HAVE_FLOAT32) &&	\
890     !defined(__clang__)
891 static inline void ALWAYS_INLINE _Float32_put(const _Float32 a)
892 {
893 	g_put_val.float_val = (float)a;
894 }
895 
896 stress_funccall_1(_Float32)
stress_funccall_2(_Float32)897 stress_funccall_2(_Float32)
898 stress_funccall_3(_Float32)
899 stress_funccall_4(_Float32)
900 stress_funccall_5(_Float32)
901 stress_funccall_6(_Float32)
902 stress_funccall_7(_Float32)
903 stress_funccall_8(_Float32)
904 stress_funccall_9(_Float32)
905 stress_funcdeep_2(_Float32)
906 stress_funcdeep_3(_Float32)
907 stress_funcdeep_4(_Float32)
908 stress_funcdeep_5(_Float32)
909 stress_funcdeep_6(_Float32)
910 stress_funcdeep_7(_Float32)
911 stress_funcdeep_8(_Float32)
912 stress_funcdeep_9(_Float32)
913 stress_funccall_type(_Float32, (_Float32)stress_mwc32)
914 #endif
915 
916 #if defined(HAVE_FLOAT64) &&	\
917     !defined(__clang__)
918 static inline void ALWAYS_INLINE _Float64_put(const _Float64 a)
919 {
920 	g_put_val.double_val = (double)a;
921 }
922 
923 stress_funccall_1(_Float64)
stress_funccall_2(_Float64)924 stress_funccall_2(_Float64)
925 stress_funccall_3(_Float64)
926 stress_funccall_4(_Float64)
927 stress_funccall_5(_Float64)
928 stress_funccall_6(_Float64)
929 stress_funccall_7(_Float64)
930 stress_funccall_8(_Float64)
931 stress_funccall_9(_Float64)
932 stress_funcdeep_2(_Float64)
933 stress_funcdeep_3(_Float64)
934 stress_funcdeep_4(_Float64)
935 stress_funcdeep_5(_Float64)
936 stress_funcdeep_6(_Float64)
937 stress_funcdeep_7(_Float64)
938 stress_funcdeep_8(_Float64)
939 stress_funcdeep_9(_Float64)
940 stress_funccall_type(_Float64, (_Float64)stress_mwc64)
941 #endif
942 
943 
944 #if defined(HAVE_FLOAT80) &&	\
945     !defined(__clang__)
946 static inline void ALWAYS_INLINE __float80_put(const __float80 a)
947 {
948 	g_put_val.double_val = (double)a;
949 }
950 
951 stress_funccall_1(__float80)
stress_funccall_2(__float80)952 stress_funccall_2(__float80)
953 stress_funccall_3(__float80)
954 stress_funccall_4(__float80)
955 stress_funccall_5(__float80)
956 stress_funccall_6(__float80)
957 stress_funccall_7(__float80)
958 stress_funccall_8(__float80)
959 stress_funccall_9(__float80)
960 stress_funcdeep_2(__float80)
961 stress_funcdeep_3(__float80)
962 stress_funcdeep_4(__float80)
963 stress_funcdeep_5(__float80)
964 stress_funcdeep_6(__float80)
965 stress_funcdeep_7(__float80)
966 stress_funcdeep_8(__float80)
967 stress_funcdeep_9(__float80)
968 stress_funccall_type(__float80, (__float80)stress_mwc64)
969 #endif
970 
971 #if defined(HAVE_FLOAT128) &&	\
972     !defined(__clang__)
973 static inline void ALWAYS_INLINE __float128_put(const __float128 a)
974 {
975 	g_put_val.double_val = (double)a;
976 }
977 
978 stress_funccall_1(__float128)
979 stress_funccall_2(__float128)
980 stress_funccall_3(__float128)
981 stress_funccall_4(__float128)
982 stress_funccall_5(__float128)
983 stress_funccall_6(__float128)
984 stress_funccall_7(__float128)
985 stress_funccall_8(__float128)
986 stress_funccall_9(__float128)
987 stress_funcdeep_2(__float128)
988 stress_funcdeep_3(__float128)
989 stress_funcdeep_4(__float128)
990 stress_funcdeep_5(__float128)
991 stress_funcdeep_6(__float128)
992 stress_funcdeep_7(__float128)
993 stress_funcdeep_8(__float128)
994 stress_funcdeep_9(__float128)
995 stress_funccall_type(__float128, (__float128)stress_mwc64)
996 #endif
997 
998 /*
999  * Table of func call stress methods
1000  */
1001 static const stress_funccall_method_info_t funccall_methods[] = {
1002 	{ "bool",	stress_funccall_bool },
1003 	{ "uint8",	stress_funccall_uint8_t },
1004 	{ "uint16",	stress_funccall_uint16_t },
1005 	{ "uint32",	stress_funccall_uint32_t },
1006 	{ "uint64",	stress_funccall_uint64_t },
1007 #if defined(HAVE_INT128_T)
1008 	{ "uint128",	stress_funccall___uint128_t },
1009 #endif
1010 	{ "float",	stress_funccall_float },
1011 #if defined(HAVE_FLOAT16) &&	\
1012     !defined(__clang__)
1013 	{ "float16",	stress_funccall___fp16 },
1014 #endif
1015 #if defined(HAVE_FLOAT32) &&	\
1016     !defined(__clang__)
1017 	{ "float32",	stress_funccall__Float32 },
1018 #endif
1019 #if defined(HAVE_FLOAT64) &&	\
1020     !defined(__clang__)
1021 	{ "float64",	stress_funccall__Float64 },
1022 #endif
1023 #if defined(HAVE_FLOAT80) &&	\
1024     !defined(__clang__)
1025 	{ "float80",	stress_funccall___float80 },
1026 #endif
1027 #if defined(HAVE_FLOAT128) &&	\
1028     !defined(__clang__)
1029 	{ "float128",	stress_funccall___float128 },
1030 #endif
1031 	{ "double",	stress_funccall_double },
1032 	{ "longdouble",	stress_funccall_stress_long_double_t },
1033 #if defined(HAVE_COMPLEX_H) &&			\
1034     defined(HAVE_COMPLEX) &&			\
1035     defined(__STDC_IEC_559_COMPLEX__) &&	\
1036     !defined(__UCLIBC__)
1037 	{ "cfloat",	stress_funccall_stress_complex_float_t },
1038 	{ "cdouble",	stress_funccall_stress_complex_double_t },
1039 	{ "clongdouble",stress_funccall_stress_complex_long_double_t },
1040 #endif
1041 #if defined(HAVE_FLOAT_DECIMAL32) &&	\
1042     !defined(__clang__)
1043 	{ "decimal32",	stress_funccall__Decimal32 },
1044 #endif
1045 #if defined(HAVE_FLOAT_DECIMAL64) &&	\
1046      !defined(__clang__)
1047 	{ "decimal64",	stress_funccall__Decimal64 },
1048 #endif
1049 #if defined(HAVE_FLOAT_DECIMAL128) &&	\
1050     !defined(__clang__)
1051 	{ "decimal128",	stress_funccall__Decimal128 },
1052 #endif
1053 	{ NULL,		NULL },
1054 };
1055 
1056 /*
1057  *  stress_set_funccall_method()
1058  *	set the default funccal stress method
1059  */
stress_set_funccall_method(const char * name)1060 static int stress_set_funccall_method(const char *name)
1061 {
1062 	stress_funccall_method_info_t const *info;
1063 
1064 	for (info = funccall_methods; info->func; info++) {
1065 		if (!strcmp(info->name, name)) {
1066 			stress_set_setting("funccall-method", TYPE_ID_UINTPTR_T, &info);
1067 			return 0;
1068 		}
1069 	}
1070 
1071 	(void)fprintf(stderr, "funccall-method must be one of:");
1072 	for (info = funccall_methods; info->func; info++) {
1073 		(void)fprintf(stderr, " %s", info->name);
1074 	}
1075 	(void)fprintf(stderr, "\n");
1076 
1077 	return -1;
1078 }
1079 
1080 /*
1081  *  stress_funccall()
1082  *	stress various argument sized function calls
1083  */
stress_funccall(const stress_args_t * args)1084 static int stress_funccall(const stress_args_t *args)
1085 {
1086 	const stress_funccall_method_info_t *funccall_method = &funccall_methods[3];
1087 
1088 	(void)stress_get_setting("funccall-method", &funccall_method);
1089 
1090 	stress_set_proc_state(args->name, STRESS_STATE_RUN);
1091 
1092 	funccall_method->func(args);
1093 
1094 	stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
1095 	return EXIT_SUCCESS;
1096 }
1097 
1098 
stress_funccall_set_default(void)1099 static void stress_funccall_set_default(void)
1100 {
1101 	stress_set_funccall_method("uint64");
1102 }
1103 
1104 static const stress_opt_set_func_t opt_set_funcs[] = {
1105 	{ OPT_funccall_method,	stress_set_funccall_method },
1106 	{ 0,			NULL }
1107 };
1108 
1109 stressor_info_t stress_funccall_info = {
1110 	.stressor = stress_funccall,
1111 	.set_default = stress_funccall_set_default,
1112 	.class = CLASS_CPU,
1113 	.opt_set_funcs = opt_set_funcs,
1114 	.help = help
1115 };
1116