Update Changelog and NEWS
[glibc.git] / nptl / tst-mutex8.c
blobd2307e47e7439874d570b38e109d1c9fc2823ac4
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.
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.
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.
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/>. */
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>
27 static pthread_mutex_t *m;
28 static pthread_barrier_t b;
29 static pthread_cond_t c;
30 static bool done;
33 static void
34 cl (void *arg)
36 if (pthread_mutex_unlock (m) != 0)
38 puts ("cl: mutex_unlocked failed");
39 exit (1);
44 static void *
45 tf (void *arg)
47 if (pthread_mutex_lock (m) != 0)
49 puts ("tf: mutex_lock failed");
50 return (void *) 1l;
53 int e = pthread_barrier_wait (&b);
54 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
56 puts ("barrier_wait failed");
57 return (void *) 1l;
60 if (arg == NULL)
62 if (pthread_cond_wait (&c, m) != 0)
64 puts ("tf: cond_wait failed");
65 return (void *) 1l;
67 while (! done);
68 else
71 pthread_cleanup_push (cl, NULL);
73 if (pthread_cond_wait (&c, m) != 0)
75 puts ("tf: cond_wait failed");
76 return (void *) 1l;
79 pthread_cleanup_pop (0);
81 while (! done);
83 if (pthread_mutex_unlock (m) != 0)
85 puts ("tf: mutex_unlock failed");
86 return (void *) 1l;
89 return NULL;
93 static int
94 check_type (const char *mas, pthread_mutexattr_t *ma)
96 int e __attribute__((unused));
98 if (pthread_mutex_init (m, ma) != 0)
100 printf ("1st mutex_init failed for %s\n", mas);
101 return 1;
104 if (pthread_mutex_destroy (m) != 0)
106 printf ("immediate mutex_destroy failed for %s\n", mas);
107 return 1;
110 if (pthread_mutex_init (m, ma) != 0)
112 printf ("2nd mutex_init failed for %s\n", mas);
113 return 1;
116 if (pthread_mutex_lock (m) != 0)
118 printf ("1st mutex_lock failed for %s\n", mas);
119 return 1;
122 /* Elided mutexes don't fail destroy. If elision is not explicitly disabled
123 we don't know, so can also not check this. */
124 #ifndef ENABLE_LOCK_ELISION
125 e = pthread_mutex_destroy (m);
126 if (e == 0)
128 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
129 return 1;
131 if (e != EBUSY)
133 printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
134 mas);
135 return 1;
137 #endif
139 if (pthread_mutex_unlock (m) != 0)
141 printf ("1st mutex_unlock failed for %s\n", mas);
142 return 1;
145 if (pthread_mutex_trylock (m) != 0)
147 printf ("mutex_trylock failed for %s\n", mas);
148 return 1;
151 /* Elided mutexes don't fail destroy. */
152 #ifndef ENABLE_LOCK_ELISION
153 e = pthread_mutex_destroy (m);
154 if (e == 0)
156 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
157 return 1;
159 if (e != EBUSY)
161 printf ("\
162 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
163 mas);
164 return 1;
166 #endif
168 if (pthread_mutex_unlock (m) != 0)
170 printf ("2nd mutex_unlock failed for %s\n", mas);
171 return 1;
174 pthread_t th;
175 if (pthread_create (&th, NULL, tf, NULL) != 0)
177 puts ("1st create failed");
178 return 1;
180 done = false;
182 e = pthread_barrier_wait (&b);
183 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
185 puts ("1st barrier_wait failed");
186 return 1;
189 if (pthread_mutex_lock (m) != 0)
191 printf ("2nd mutex_lock failed for %s\n", mas);
192 return 1;
195 if (pthread_mutex_unlock (m) != 0)
197 printf ("3rd mutex_unlock failed for %s\n", mas);
198 return 1;
201 /* Elided mutexes don't fail destroy. */
202 #ifndef ENABLE_LOCK_ELISION
203 e = pthread_mutex_destroy (m);
204 if (e == 0)
206 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
207 return 1;
209 if (e != EBUSY)
211 printf ("\
212 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
213 return 1;
215 #endif
217 done = true;
218 if (pthread_cond_signal (&c) != 0)
220 puts ("cond_signal failed");
221 return 1;
224 void *r;
225 if (pthread_join (th, &r) != 0)
227 puts ("join failed");
228 return 1;
230 if (r != NULL)
232 puts ("thread didn't return NULL");
233 return 1;
236 if (pthread_mutex_destroy (m) != 0)
238 printf ("mutex_destroy after condvar-use failed for %s\n", mas);
239 return 1;
242 if (pthread_mutex_init (m, ma) != 0)
244 printf ("3rd mutex_init failed for %s\n", mas);
245 return 1;
248 if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
250 puts ("2nd create failed");
251 return 1;
253 done = false;
255 e = pthread_barrier_wait (&b);
256 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
258 puts ("2nd barrier_wait failed");
259 return 1;
262 if (pthread_mutex_lock (m) != 0)
264 printf ("3rd mutex_lock failed for %s\n", mas);
265 return 1;
268 if (pthread_mutex_unlock (m) != 0)
270 printf ("4th mutex_unlock failed for %s\n", mas);
271 return 1;
274 /* Elided mutexes don't fail destroy. */
275 #ifndef ENABLE_LOCK_ELISION
276 e = pthread_mutex_destroy (m);
277 if (e == 0)
279 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
280 mas);
281 return 1;
283 if (e != EBUSY)
285 printf ("\
286 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
287 mas);
288 return 1;
290 #endif
292 if (pthread_cancel (th) != 0)
294 puts ("cond_cancel failed");
295 return 1;
298 if (pthread_join (th, &r) != 0)
300 puts ("join failed");
301 return 1;
303 if (r != PTHREAD_CANCELED)
305 puts ("thread not canceled");
306 return 1;
309 if (pthread_mutex_destroy (m) != 0)
311 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
312 return 1;
315 return 0;
319 static int
320 do_test (void)
322 pthread_mutex_t mm;
323 m = &mm;
325 if (pthread_barrier_init (&b, NULL, 2) != 0)
327 puts ("barrier_init failed");
328 return 1;
331 if (pthread_cond_init (&c, NULL) != 0)
333 puts ("cond_init failed");
334 return 1;
337 puts ("check normal mutex");
338 int res = check_type ("normal", NULL);
340 pthread_mutexattr_t ma;
341 if (pthread_mutexattr_init (&ma) != 0)
343 puts ("1st mutexattr_init failed");
344 return 1;
346 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
348 puts ("1st mutexattr_settype failed");
349 return 1;
351 #ifdef ENABLE_PI
352 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
354 puts ("1st pthread_mutexattr_setprotocol failed");
355 return 1;
357 #endif
358 puts ("check recursive mutex");
359 res |= check_type ("recursive", &ma);
360 if (pthread_mutexattr_destroy (&ma) != 0)
362 puts ("1st mutexattr_destroy failed");
363 return 1;
366 if (pthread_mutexattr_init (&ma) != 0)
368 puts ("2nd mutexattr_init failed");
369 return 1;
371 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
373 puts ("2nd mutexattr_settype failed");
374 return 1;
376 #ifdef ENABLE_PI
377 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
379 puts ("2nd pthread_mutexattr_setprotocol failed");
380 return 1;
382 #endif
383 puts ("check error-checking mutex");
384 res |= check_type ("error-checking", &ma);
385 if (pthread_mutexattr_destroy (&ma) != 0)
387 puts ("2nd mutexattr_destroy failed");
388 return 1;
391 return res;
394 #define TEST_FUNCTION do_test ()
395 #include "../test-skeleton.c"