xref: /openbsd-src/regress/sys/kern/signal/fpsig/fpsig.c (revision 5c33ecfc8b074dc221a195406b4caaf4aa7d7fef)
1 /*	$OpenBSD: fpsig.c,v 1.4 2022/10/28 16:06:54 miod Exp $	*/
2 
3 /*
4  * Public domain.  2005, Otto Moerbeek
5  *
6  * Try to check if fp registers are properly saved and restored while
7  * calling a signal hander.  This is not supposed to catch all that
8  * can go wrong, but trashed fp registers will typically get caught.
9  */
10 
11 #include <err.h>
12 #include <signal.h>
13 #include <unistd.h>
14 #include <sys/time.h>
15 
16 #define LIMIT	11.1
17 
18 volatile sig_atomic_t count;
19 
20 volatile double g1;
21 volatile double g2;
22 
23 void
handler(int signo)24 handler(int signo)
25 {
26 	double a, b, c = 0.0;
27 
28 	for (a = 0.0; a < LIMIT; a += 1.1)
29 		for (b = 0.0; b < LIMIT; b += 1.1)
30 			c += a * a + b * b;
31 
32 	if (signo) {
33 		g1 = c;
34 		count++;
35 	} else
36 		g2 = c;
37 }
38 
39 int
main()40 main()
41 {
42 	struct itimerval it = {
43 		.it_interval =  { .tv_sec = 0, .tv_usec = 10000 },
44 		.it_value =  { .tv_sec = 0, .tv_usec = 10000 }
45 	};
46 
47 	/* initialize global vars */
48 	handler(0);
49 	handler(1);
50 
51 	signal(SIGALRM, handler);
52 	setitimer(ITIMER_REAL, &it, NULL);
53 
54 	while (count < 10000) {
55 		handler(0);
56 
57 		double a, b, h1 = g1, h2 = g2;
58 
59 		for (a = 0.0; a < LIMIT; a += 1.1)
60 			for (b = 0.0; b < LIMIT; b += 1.1)
61 				h1 += a * a + b * b;
62 		for (a = 0.0; a < LIMIT; a += 1.1)
63 			for (b = 0.0; b < LIMIT; b += 1.1)
64 				h2 += a * a + b * b;
65 
66 		if (h1 != h2)
67 			errx(1, "%f %f", g1, g2);
68 	}
69 	return (0);
70 }
71