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