string: Hook up the default implementation on test-memchr
[glibc.git] / nptl / tst-mutex8.c
blob4ac5f5059f37433ccddf9bc03bd86d69180ea4a6
1 /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
18 /* This test checks behavior not required by POSIX. */
19 #include <errno.h>
20 #include <pthread.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <elf/dl-tunables.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;
98 /* Check if a mutex will be elided. Lock elision can only be activated via
99 the tunables framework. By default, lock elision is disabled. */
100 bool assume_elided_mutex = false;
101 #if HAVE_TUNABLES
102 int ma_type = PTHREAD_MUTEX_TIMED_NP;
103 if (ma != NULL)
105 e = pthread_mutexattr_gettype (ma, &ma_type);
106 if (e != 0)
108 printf ("pthread_mutexattr_gettype failed with %d (%m)\n", e);
109 return 1;
112 if (ma_type == PTHREAD_MUTEX_TIMED_NP)
114 /* This type of mutex can be elided if elision is enabled via the tunables
115 framework. Some tests below are failing if the mutex is elided.
116 Thus we only run those if we assume that the mutex won't be elided. */
117 if (TUNABLE_GET_FULL (glibc, elision, enable, int32_t, NULL) == 1)
118 assume_elided_mutex = true;
120 #endif
122 e = pthread_mutex_init (m, ma);
123 if (e != 0)
125 #ifdef ENABLE_PI
126 if (e == ENOTSUP)
128 puts ("PI mutexes unsupported");
129 return 0;
131 #endif
132 printf ("1st mutex_init failed for %s\n", mas);
133 return 1;
136 if (pthread_mutex_destroy (m) != 0)
138 printf ("immediate mutex_destroy failed for %s\n", mas);
139 return 1;
142 if (pthread_mutex_init (m, ma) != 0)
144 printf ("2nd mutex_init failed for %s\n", mas);
145 return 1;
148 if (pthread_mutex_lock (m) != 0)
150 printf ("1st mutex_lock failed for %s\n", mas);
151 return 1;
154 /* Elided mutexes don't fail destroy, thus only test this if we don't assume
155 elision. */
156 if (assume_elided_mutex == false)
158 e = pthread_mutex_destroy (m);
159 if (e == 0)
161 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
162 return 1;
164 if (e != EBUSY)
166 printf ("\
167 mutex_destroy of self-locked mutex did not return EBUSY %s\n",
168 mas);
169 return 1;
173 if (pthread_mutex_unlock (m) != 0)
175 printf ("1st mutex_unlock failed for %s\n", mas);
176 return 1;
179 if (pthread_mutex_trylock (m) != 0)
181 printf ("mutex_trylock failed for %s\n", mas);
182 return 1;
185 /* Elided mutexes don't fail destroy. */
186 if (assume_elided_mutex == false)
188 e = pthread_mutex_destroy (m);
189 if (e == 0)
191 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n",
192 mas);
193 return 1;
195 if (e != EBUSY)
197 printf ("\
198 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
199 mas);
200 return 1;
204 if (pthread_mutex_unlock (m) != 0)
206 printf ("2nd mutex_unlock failed for %s\n", mas);
207 return 1;
210 pthread_t th;
211 if (pthread_create (&th, NULL, tf, NULL) != 0)
213 puts ("1st create failed");
214 return 1;
216 done = false;
218 e = pthread_barrier_wait (&b);
219 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
221 puts ("1st barrier_wait failed");
222 return 1;
225 if (pthread_mutex_lock (m) != 0)
227 printf ("2nd mutex_lock failed for %s\n", mas);
228 return 1;
231 if (pthread_mutex_unlock (m) != 0)
233 printf ("3rd mutex_unlock failed for %s\n", mas);
234 return 1;
237 /* Elided mutexes don't fail destroy. */
238 if (assume_elided_mutex == false)
240 e = pthread_mutex_destroy (m);
241 if (e == 0)
243 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n",
244 mas);
245 return 1;
247 if (e != EBUSY)
249 printf ("\
250 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
251 return 1;
255 done = true;
256 if (pthread_cond_signal (&c) != 0)
258 puts ("cond_signal failed");
259 return 1;
262 void *r;
263 if (pthread_join (th, &r) != 0)
265 puts ("join failed");
266 return 1;
268 if (r != NULL)
270 puts ("thread didn't return NULL");
271 return 1;
274 if (pthread_mutex_destroy (m) != 0)
276 printf ("mutex_destroy after condvar-use failed for %s\n", mas);
277 return 1;
280 if (pthread_mutex_init (m, ma) != 0)
282 printf ("3rd mutex_init failed for %s\n", mas);
283 return 1;
286 if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
288 puts ("2nd create failed");
289 return 1;
291 done = false;
293 e = pthread_barrier_wait (&b);
294 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
296 puts ("2nd barrier_wait failed");
297 return 1;
300 if (pthread_mutex_lock (m) != 0)
302 printf ("3rd mutex_lock failed for %s\n", mas);
303 return 1;
306 if (pthread_mutex_unlock (m) != 0)
308 printf ("4th mutex_unlock failed for %s\n", mas);
309 return 1;
312 /* Elided mutexes don't fail destroy. */
313 if (assume_elided_mutex == false)
315 e = pthread_mutex_destroy (m);
316 if (e == 0)
318 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
319 mas);
320 return 1;
322 if (e != EBUSY)
324 printf ("\
325 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
326 mas);
327 return 1;
331 if (pthread_cancel (th) != 0)
333 puts ("cond_cancel failed");
334 return 1;
337 if (pthread_join (th, &r) != 0)
339 puts ("join failed");
340 return 1;
342 if (r != PTHREAD_CANCELED)
344 puts ("thread not canceled");
345 return 1;
348 if (pthread_mutex_destroy (m) != 0)
350 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
351 return 1;
354 return 0;
358 static int
359 do_test (void)
361 pthread_mutex_t mm;
362 m = &mm;
364 if (pthread_barrier_init (&b, NULL, 2) != 0)
366 puts ("barrier_init failed");
367 return 1;
370 if (pthread_cond_init (&c, NULL) != 0)
372 puts ("cond_init failed");
373 return 1;
376 puts ("check normal mutex");
377 int res = check_type ("normal", NULL);
379 pthread_mutexattr_t ma;
380 if (pthread_mutexattr_init (&ma) != 0)
382 puts ("1st mutexattr_init failed");
383 return 1;
385 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
387 puts ("1st mutexattr_settype failed");
388 return 1;
390 #ifdef ENABLE_PI
391 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
393 puts ("1st pthread_mutexattr_setprotocol failed");
394 return 1;
396 #endif
397 puts ("check recursive mutex");
398 res |= check_type ("recursive", &ma);
399 if (pthread_mutexattr_destroy (&ma) != 0)
401 puts ("1st mutexattr_destroy failed");
402 return 1;
405 if (pthread_mutexattr_init (&ma) != 0)
407 puts ("2nd mutexattr_init failed");
408 return 1;
410 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
412 puts ("2nd mutexattr_settype failed");
413 return 1;
415 #ifdef ENABLE_PI
416 if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT))
418 puts ("2nd pthread_mutexattr_setprotocol failed");
419 return 1;
421 #endif
422 puts ("check error-checking mutex");
423 res |= check_type ("error-checking", &ma);
424 if (pthread_mutexattr_destroy (&ma) != 0)
426 puts ("2nd mutexattr_destroy failed");
427 return 1;
430 return res;
433 #define TEST_FUNCTION do_test ()
434 #include "../test-skeleton.c"