NPTL is no longer an add-on!
[platform/upstream/glibc.git] / math / test-fenv-tls.c
1 /* Test floating-point environment is thread-local.
2    Copyright (C) 2013-2014 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <fenv.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdint.h>
23
24 #define TEST_ONE_RM(RM)                                         \
25   do                                                            \
26     {                                                           \
27       if (fesetround (RM) == 0)                                 \
28         {                                                       \
29           rm = fegetround ();                                   \
30           if (rm != RM)                                         \
31             {                                                   \
32               printf ("expected " #RM ", got %d\n", rm);        \
33               ret = 1;                                          \
34             }                                                   \
35         }                                                       \
36     }                                                           \
37   while (0)
38
39 static void *
40 test_round (void *arg)
41 {
42   intptr_t ret = 0;
43   for (int i = 0; i < 10000; i++)
44     {
45       int rm;
46 #ifdef FE_DOWNWARD
47       TEST_ONE_RM (FE_DOWNWARD);
48 #endif
49 #ifdef FE_TONEAREST
50       TEST_ONE_RM (FE_TONEAREST);
51 #endif
52 #ifdef FE_TOWARDZERO
53       TEST_ONE_RM (FE_TOWARDZERO);
54 #endif
55 #ifdef FE_UPWARD
56       TEST_ONE_RM (FE_UPWARD);
57 #endif
58     }
59   return (void *) ret;
60 }
61
62 #define TEST_ONE_RAISE(EX)                              \
63   do                                                    \
64     {                                                   \
65       if (feraiseexcept (EX) == 0)                      \
66         if (fetestexcept (EX) != EX)                    \
67           {                                             \
68             printf (#EX " not raised\n");               \
69             ret = 1;                                    \
70           }                                             \
71       if (feclearexcept (FE_ALL_EXCEPT) == 0)           \
72         if (fetestexcept (FE_ALL_EXCEPT) != 0)          \
73           {                                             \
74             printf ("exceptions not all cleared\n");    \
75             ret = 1;                                    \
76           }                                             \
77     }                                                   \
78   while (0)
79
80 static void *
81 test_raise (void *arg)
82 {
83   intptr_t ret = 0;
84   for (int i = 0; i < 10000; i++)
85     {
86 #ifdef FE_DIVBYZERO
87       TEST_ONE_RAISE (FE_DIVBYZERO);
88 #endif
89 #ifdef FE_INEXACT
90       TEST_ONE_RAISE (FE_INEXACT);
91 #endif
92 #ifdef FE_INVALID
93       TEST_ONE_RAISE (FE_INVALID);
94 #endif
95 #ifdef FE_OVERFLOW
96       TEST_ONE_RAISE (FE_OVERFLOW);
97 #endif
98 #ifdef UNDERFLOW
99       TEST_ONE_RAISE (FE_UNDERFLOW);
100 #endif
101     }
102   return (void *) ret;
103 }
104
105 #define TEST_ONE_ENABLE(EX)                             \
106   do                                                    \
107     {                                                   \
108       if (feenableexcept (EX) != -1)                    \
109         if (fegetexcept () != EX)                       \
110           {                                             \
111             printf (#EX " not enabled\n");              \
112             ret = 1;                                    \
113           }                                             \
114       if (fedisableexcept (EX) != -1)                   \
115         if (fegetexcept () != 0)                        \
116           {                                             \
117             printf ("exceptions not all disabled\n");   \
118             ret = 1;                                    \
119           }                                             \
120     }                                                   \
121   while (0)
122
123 static void *
124 test_enable (void *arg)
125 {
126   intptr_t ret = 0;
127   for (int i = 0; i < 10000; i++)
128     {
129 #ifdef FE_DIVBYZERO
130       TEST_ONE_ENABLE (FE_DIVBYZERO);
131 #endif
132 #ifdef FE_INEXACT
133       TEST_ONE_ENABLE (FE_INEXACT);
134 #endif
135 #ifdef FE_INVALID
136       TEST_ONE_ENABLE (FE_INVALID);
137 #endif
138 #ifdef FE_OVERFLOW
139       TEST_ONE_ENABLE (FE_OVERFLOW);
140 #endif
141 #ifdef UNDERFLOW
142       TEST_ONE_ENABLE (FE_UNDERFLOW);
143 #endif
144     }
145   return (void *) ret;
146 }
147
148 static int
149 do_test (void)
150 {
151   int ret = 0;
152   void *vret;
153   pthread_t thread_id;
154   int pret;
155
156   pret = pthread_create (&thread_id, NULL, test_round, NULL);
157   if (pret != 0)
158     {
159       printf ("pthread_create failed: %d\n", pret);
160       return 1;
161     }
162   vret = test_round (NULL);
163   ret |= (intptr_t) vret;
164   pret = pthread_join (thread_id, &vret);
165   if (pret != 0)
166     {
167       printf ("pthread_join failed: %d\n", pret);
168       return 1;
169     }
170   ret |= (intptr_t) vret;
171
172   pret = pthread_create (&thread_id, NULL, test_raise, NULL);
173   if (pret != 0)
174     {
175       printf ("pthread_create failed: %d\n", pret);
176       return 1;
177     }
178   vret = test_raise (NULL);
179   ret |= (intptr_t) vret;
180   pret = pthread_join (thread_id, &vret);
181   if (pret != 0)
182     {
183       printf ("pthread_join failed: %d\n", pret);
184       return 1;
185     }
186   ret |= (intptr_t) vret;
187
188   pret = pthread_create (&thread_id, NULL, test_enable, NULL);
189   if (pret != 0)
190     {
191       printf ("pthread_create failed: %d\n", pret);
192       return 1;
193     }
194   vret = test_enable (NULL);
195   ret |= (intptr_t) vret;
196   pret = pthread_join (thread_id, &vret);
197   if (pret != 0)
198     {
199       printf ("pthread_join failed: %d\n", pret);
200       return 1;
201     }
202   ret |= (intptr_t) vret;
203
204   return ret;
205 }
206
207 #define TEST_FUNCTION do_test ()
208 #include "../test-skeleton.c"