universally apply our cflags (no vsx, no altivec..)
[glibc.git] / fbtl / tst-mutex8.c
1 /* Copyright (C) 2003-2013 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
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 /* This test checks behavior not required by POSIX. */
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26
27 static pthread_mutex_t *m;
28 static pthread_barrier_t b;
29 static pthread_cond_t c;
30 static bool done;
31
32
33 static void
34 cl (void *arg)
35 {
36 if (pthread_mutex_unlock (m) != 0)
37 {
38 puts ("cl: mutex_unlocked failed");
39 exit (1);
40 }
41 }
42
43
44 static void *
45 tf (void *arg)
46 {
47 if (pthread_mutex_lock (m) != 0)
48 {
49 puts ("tf: mutex_lock failed");
50 return (void *) 1l;
51 }
52
53 int e = pthread_barrier_wait (&b);
54 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
55 {
56 puts ("barrier_wait failed");
57 return (void *) 1l;
58 }
59
60 if (arg == NULL)
61 do
62 if (pthread_cond_wait (&c, m) != 0)
63 {
64 puts ("tf: cond_wait failed");
65 return (void *) 1l;
66 }
67 while (! done);
68 else
69 do
70 {
71 pthread_cleanup_push (cl, NULL);
72
73 if (pthread_cond_wait (&c, m) != 0)
74 {
75 puts ("tf: cond_wait failed");
76 return (void *) 1l;
77 }
78
79 pthread_cleanup_pop (0);
80 }
81 while (! done);
82
83 if (pthread_mutex_unlock (m) != 0)
84 {
85 puts ("tf: mutex_unlock failed");
86 return (void *) 1l;
87 }
88
89 return NULL;
90 }
91
92
93 static int
94 check_type (const char *mas, pthread_mutexattr_t *ma)
95 {
96 if (pthread_mutex_init (m, ma) != 0)
97 {
98 printf ("1st mutex_init failed for %s\n", mas);
99 return 1;
100 }
101
102 if (pthread_mutex_destroy (m) != 0)
103 {
104 printf ("immediate mutex_destroy failed for %s\n", mas);
105 return 1;
106 }
107
108 if (pthread_mutex_init (m, ma) != 0)
109 {
110 printf ("2nd mutex_init failed for %s\n", mas);
111 return 1;
112 }
113
114 if (pthread_mutex_lock (m) != 0)
115 {
116 printf ("1st mutex_lock failed for %s\n", mas);
117 return 1;
118 }
119
120 int e = pthread_mutex_destroy (m);
121 if (e == 0)
122 {
123 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
124 return 1;
125 }
126 if (e != EBUSY)
127 {
128 printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
129 mas);
130 return 1;
131 }
132
133 if (pthread_mutex_unlock (m) != 0)
134 {
135 printf ("1st mutex_unlock failed for %s\n", mas);
136 return 1;
137 }
138
139 if (pthread_mutex_trylock (m) != 0)
140 {
141 printf ("mutex_trylock failed for %s\n", mas);
142 return 1;
143 }
144
145 e = pthread_mutex_destroy (m);
146 if (e == 0)
147 {
148 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
149 return 1;
150 }
151 if (e != EBUSY)
152 {
153 printf ("\
154 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
155 mas);
156 return 1;
157 }
158
159 if (pthread_mutex_unlock (m) != 0)
160 {
161 printf ("2nd mutex_unlock failed for %s\n", mas);
162 return 1;
163 }
164
165 pthread_t th;
166 if (pthread_create (&th, NULL, tf, NULL) != 0)
167 {
168 puts ("1st create failed");
169 return 1;
170 }
171 done = false;
172
173 e = pthread_barrier_wait (&b);
174 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
175 {
176 puts ("1st barrier_wait failed");
177 return 1;
178 }
179
180 if (pthread_mutex_lock (m) != 0)
181 {
182 printf ("2nd mutex_lock failed for %s\n", mas);
183 return 1;
184 }
185
186 if (pthread_mutex_unlock (m) != 0)
187 {
188 printf ("3rd mutex_unlock failed for %s\n", mas);
189 return 1;
190 }
191
192 e = pthread_mutex_destroy (m);
193 if (e == 0)
194 {
195 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
196 return 1;
197 }
198 if (e != EBUSY)
199 {
200 printf ("\
201 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
202 return 1;
203 }
204
205 done = true;
206 if (pthread_cond_signal (&c) != 0)
207 {
208 puts ("cond_signal failed");
209 return 1;
210 }
211
212 void *r;
213 if (pthread_join (th, &r) != 0)
214 {
215 puts ("join failed");
216 return 1;
217 }
218 if (r != NULL)
219 {
220 puts ("thread didn't return NULL");
221 return 1;
222 }
223
224 if (pthread_mutex_destroy (m) != 0)
225 {
226 printf ("mutex_destroy after condvar-use failed for %s\n", mas);
227 return 1;
228 }
229
230 if (pthread_mutex_init (m, ma) != 0)
231 {
232 printf ("3rd mutex_init failed for %s\n", mas);
233 return 1;
234 }
235
236 if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
237 {
238 puts ("2nd create failed");
239 return 1;
240 }
241 done = false;
242
243 e = pthread_barrier_wait (&b);
244 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
245 {
246 puts ("2nd barrier_wait failed");
247 return 1;
248 }
249
250 if (pthread_mutex_lock (m) != 0)
251 {
252 printf ("3rd mutex_lock failed for %s\n", mas);
253 return 1;
254 }
255
256 if (pthread_mutex_unlock (m) != 0)
257 {
258 printf ("4th mutex_unlock failed for %s\n", mas);
259 return 1;
260 }
261
262 e = pthread_mutex_destroy (m);
263 if (e == 0)
264 {
265 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
266 mas);
267 return 1;
268 }
269 if (e != EBUSY)
270 {
271 printf ("\
272 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
273 mas);
274 return 1;
275 }
276
277 if (pthread_cancel (th) != 0)
278 {
279 puts ("cond_cancel failed");
280 return 1;
281 }
282
283 if (pthread_join (th, &r) != 0)
284 {
285 puts ("join failed");
286 return 1;
287 }
288 if (r != PTHREAD_CANCELED)
289 {
290 puts ("thread not canceled");
291 return 1;
292 }
293
294 if (pthread_mutex_destroy (m) != 0)
295 {
296 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
297 return 1;
298 }
299
300 return 0;
301 }
302
303
304 static int
305 do_test (void)
306 {
307 pthread_mutex_t mm;
308 m = &mm;
309
310 if (pthread_barrier_init (&b, NULL, 2) != 0)
311 {
312 puts ("barrier_init failed");
313 return 1;
314 }
315
316 if (pthread_cond_init (&c, NULL) != 0)
317 {
318 puts ("cond_init failed");
319 return 1;
320 }
321
322 puts ("check normal mutex");
323 int res = check_type ("normal", NULL);
324
325 pthread_mutexattr_t ma;
326 if (pthread_mutexattr_init (&ma) != 0)
327 {
328 puts ("1st mutexattr_init failed");
329 return 1;
330 }
331 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
332 {
333 puts ("1st mutexattr_settype failed");
334 return 1;
335 }
336 #ifdef ENABLE_PI
337 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
338 {
339 puts ("1st pthread_mutexattr_setprotocol failed");
340 return 1;
341 }
342 #endif
343 puts ("check recursive mutex");
344 res |= check_type ("recursive", &ma);
345 if (pthread_mutexattr_destroy (&ma) != 0)
346 {
347 puts ("1st mutexattr_destroy failed");
348 return 1;
349 }
350
351 if (pthread_mutexattr_init (&ma) != 0)
352 {
353 puts ("2nd mutexattr_init failed");
354 return 1;
355 }
356 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
357 {
358 puts ("2nd mutexattr_settype failed");
359 return 1;
360 }
361 #ifdef ENABLE_PI
362 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
363 {
364 puts ("2nd pthread_mutexattr_setprotocol failed");
365 return 1;
366 }
367 #endif
368 puts ("check error-checking mutex");
369 res |= check_type ("error-checking", &ma);
370 if (pthread_mutexattr_destroy (&ma) != 0)
371 {
372 puts ("2nd mutexattr_destroy failed");
373 return 1;
374 }
375
376 return res;
377 }
378
379 #define TEST_FUNCTION do_test ()
380 #include "../test-skeleton.c"