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