]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/tst-mutex8.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / nptl / tst-mutex8.c
CommitLineData
b168057a 1/* Copyright (C) 2003-2015 Free Software Foundation, Inc.
61623643
UD
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
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
61623643
UD
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
27static pthread_mutex_t *m;
28static pthread_barrier_t b;
29static pthread_cond_t c;
30static bool done;
31
32
33static void
34cl (void *arg)
35{
36 if (pthread_mutex_unlock (m) != 0)
37 {
38 puts ("cl: mutex_unlocked failed");
39 exit (1);
40 }
41}
42
43
44static void *
45tf (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
93static int
94check_type (const char *mas, pthread_mutexattr_t *ma)
95{
53247a0b 96 int e;
68cc2935 97
53247a0b
MR
98 e = pthread_mutex_init (m, ma);
99 if (e != 0)
61623643 100 {
53247a0b
MR
101#ifdef ENABLE_PI
102 if (e == ENOTSUP)
103 {
104 puts ("PI mutexes unsupported");
105 return 0;
106 }
107#endif
61623643
UD
108 printf ("1st mutex_init failed for %s\n", mas);
109 return 1;
110 }
111
112 if (pthread_mutex_destroy (m) != 0)
113 {
114 printf ("immediate mutex_destroy failed for %s\n", mas);
115 return 1;
116 }
117
118 if (pthread_mutex_init (m, ma) != 0)
119 {
120 printf ("2nd mutex_init failed for %s\n", mas);
121 return 1;
122 }
123
124 if (pthread_mutex_lock (m) != 0)
125 {
126 printf ("1st mutex_lock failed for %s\n", mas);
127 return 1;
128 }
129
68cc2935
AK
130 /* Elided mutexes don't fail destroy. If elision is not explicitly disabled
131 we don't know, so can also not check this. */
132#ifndef ENABLE_LOCK_ELISION
133 e = pthread_mutex_destroy (m);
61623643
UD
134 if (e == 0)
135 {
136 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
137 return 1;
138 }
139 if (e != EBUSY)
140 {
141 printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
142 mas);
143 return 1;
144 }
68cc2935 145#endif
61623643
UD
146
147 if (pthread_mutex_unlock (m) != 0)
148 {
149 printf ("1st mutex_unlock failed for %s\n", mas);
150 return 1;
151 }
152
153 if (pthread_mutex_trylock (m) != 0)
154 {
155 printf ("mutex_trylock failed for %s\n", mas);
156 return 1;
157 }
158
68cc2935
AK
159 /* Elided mutexes don't fail destroy. */
160#ifndef ENABLE_LOCK_ELISION
61623643
UD
161 e = pthread_mutex_destroy (m);
162 if (e == 0)
163 {
164 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
165 return 1;
166 }
167 if (e != EBUSY)
168 {
169 printf ("\
170mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
171 mas);
172 return 1;
173 }
68cc2935 174#endif
61623643
UD
175
176 if (pthread_mutex_unlock (m) != 0)
177 {
178 printf ("2nd mutex_unlock failed for %s\n", mas);
179 return 1;
180 }
181
182 pthread_t th;
183 if (pthread_create (&th, NULL, tf, NULL) != 0)
184 {
185 puts ("1st create failed");
186 return 1;
187 }
188 done = false;
189
190 e = pthread_barrier_wait (&b);
191 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
192 {
193 puts ("1st barrier_wait failed");
194 return 1;
195 }
196
197 if (pthread_mutex_lock (m) != 0)
198 {
199 printf ("2nd mutex_lock failed for %s\n", mas);
200 return 1;
201 }
202
203 if (pthread_mutex_unlock (m) != 0)
204 {
205 printf ("3rd mutex_unlock failed for %s\n", mas);
206 return 1;
207 }
208
68cc2935
AK
209 /* Elided mutexes don't fail destroy. */
210#ifndef ENABLE_LOCK_ELISION
61623643
UD
211 e = pthread_mutex_destroy (m);
212 if (e == 0)
213 {
214 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
215 return 1;
216 }
217 if (e != EBUSY)
218 {
219 printf ("\
220mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
221 return 1;
222 }
68cc2935 223#endif
61623643
UD
224
225 done = true;
226 if (pthread_cond_signal (&c) != 0)
227 {
228 puts ("cond_signal failed");
229 return 1;
230 }
231
232 void *r;
233 if (pthread_join (th, &r) != 0)
234 {
235 puts ("join failed");
236 return 1;
237 }
238 if (r != NULL)
239 {
240 puts ("thread didn't return NULL");
241 return 1;
242 }
243
244 if (pthread_mutex_destroy (m) != 0)
245 {
246 printf ("mutex_destroy after condvar-use failed for %s\n", mas);
247 return 1;
248 }
249
250 if (pthread_mutex_init (m, ma) != 0)
251 {
252 printf ("3rd mutex_init failed for %s\n", mas);
253 return 1;
254 }
255
256 if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
257 {
258 puts ("2nd create failed");
259 return 1;
260 }
261 done = false;
262
263 e = pthread_barrier_wait (&b);
264 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
265 {
266 puts ("2nd barrier_wait failed");
267 return 1;
268 }
269
270 if (pthread_mutex_lock (m) != 0)
271 {
272 printf ("3rd mutex_lock failed for %s\n", mas);
273 return 1;
274 }
275
276 if (pthread_mutex_unlock (m) != 0)
277 {
278 printf ("4th mutex_unlock failed for %s\n", mas);
279 return 1;
280 }
281
68cc2935
AK
282 /* Elided mutexes don't fail destroy. */
283#ifndef ENABLE_LOCK_ELISION
61623643
UD
284 e = pthread_mutex_destroy (m);
285 if (e == 0)
286 {
287 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
288 mas);
289 return 1;
290 }
291 if (e != EBUSY)
292 {
293 printf ("\
2942nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
295 mas);
296 return 1;
297 }
68cc2935 298#endif
61623643
UD
299
300 if (pthread_cancel (th) != 0)
301 {
302 puts ("cond_cancel failed");
303 return 1;
304 }
305
306 if (pthread_join (th, &r) != 0)
307 {
308 puts ("join failed");
309 return 1;
310 }
311 if (r != PTHREAD_CANCELED)
312 {
313 puts ("thread not canceled");
314 return 1;
315 }
316
317 if (pthread_mutex_destroy (m) != 0)
318 {
319 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
320 return 1;
321 }
322
323 return 0;
324}
325
326
327static int
328do_test (void)
329{
330 pthread_mutex_t mm;
331 m = &mm;
332
333 if (pthread_barrier_init (&b, NULL, 2) != 0)
334 {
335 puts ("barrier_init failed");
336 return 1;
337 }
338
339 if (pthread_cond_init (&c, NULL) != 0)
340 {
341 puts ("cond_init failed");
342 return 1;
343 }
344
345 puts ("check normal mutex");
346 int res = check_type ("normal", NULL);
347
348 pthread_mutexattr_t ma;
349 if (pthread_mutexattr_init (&ma) != 0)
350 {
351 puts ("1st mutexattr_init failed");
352 return 1;
353 }
354 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
355 {
356 puts ("1st mutexattr_settype failed");
357 return 1;
358 }
66c13581
AK
359#ifdef ENABLE_PI
360 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
361 {
362 puts ("1st pthread_mutexattr_setprotocol failed");
363 return 1;
364 }
365#endif
61623643
UD
366 puts ("check recursive mutex");
367 res |= check_type ("recursive", &ma);
368 if (pthread_mutexattr_destroy (&ma) != 0)
369 {
370 puts ("1st mutexattr_destroy failed");
371 return 1;
372 }
373
374 if (pthread_mutexattr_init (&ma) != 0)
375 {
376 puts ("2nd mutexattr_init failed");
377 return 1;
378 }
379 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
380 {
381 puts ("2nd mutexattr_settype failed");
382 return 1;
383 }
66c13581
AK
384#ifdef ENABLE_PI
385 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
386 {
387 puts ("2nd pthread_mutexattr_setprotocol failed");
388 return 1;
389 }
390#endif
61623643
UD
391 puts ("check error-checking mutex");
392 res |= check_type ("error-checking", &ma);
393 if (pthread_mutexattr_destroy (&ma) != 0)
394 {
395 puts ("2nd mutexattr_destroy failed");
396 return 1;
397 }
398
399 return res;
400}
401
402#define TEST_FUNCTION do_test ()
403#include "../test-skeleton.c"