1 /* Copyright (C) 2003-2024 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. */
25 #include <elf/dl-tunables.h>
27 static pthread_mutex_t
*m
;
28 static pthread_barrier_t b
;
29 static pthread_cond_t c
;
36 if (pthread_mutex_unlock (m
) != 0)
38 puts ("cl: mutex_unlocked failed");
47 if (pthread_mutex_lock (m
) != 0)
49 puts ("tf: mutex_lock failed");
53 int e
= pthread_barrier_wait (&b
);
54 if (e
!= 0 && e
!= PTHREAD_BARRIER_SERIAL_THREAD
)
56 puts ("barrier_wait failed");
62 if (pthread_cond_wait (&c
, m
) != 0)
64 puts ("tf: cond_wait failed");
71 pthread_cleanup_push (cl
, NULL
);
73 if (pthread_cond_wait (&c
, m
) != 0)
75 puts ("tf: cond_wait failed");
79 pthread_cleanup_pop (0);
83 if (pthread_mutex_unlock (m
) != 0)
85 puts ("tf: mutex_unlock failed");
94 check_type (const char *mas
, pthread_mutexattr_t
*ma
)
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 int ma_type
= PTHREAD_MUTEX_TIMED_NP
;
104 e
= pthread_mutexattr_gettype (ma
, &ma_type
);
107 printf ("pthread_mutexattr_gettype failed with %d (%m)\n", e
);
111 if (ma_type
== PTHREAD_MUTEX_TIMED_NP
)
113 /* This type of mutex can be elided if elision is enabled via the tunables
114 framework. Some tests below are failing if the mutex is elided.
115 Thus we only run those if we assume that the mutex won't be elided. */
116 if (TUNABLE_GET_FULL (glibc
, elision
, enable
, int32_t, NULL
) == 1)
117 assume_elided_mutex
= true;
120 e
= pthread_mutex_init (m
, ma
);
126 puts ("PI mutexes unsupported");
130 printf ("1st mutex_init failed for %s\n", mas
);
134 if (pthread_mutex_destroy (m
) != 0)
136 printf ("immediate mutex_destroy failed for %s\n", mas
);
140 if (pthread_mutex_init (m
, ma
) != 0)
142 printf ("2nd mutex_init failed for %s\n", mas
);
146 if (pthread_mutex_lock (m
) != 0)
148 printf ("1st mutex_lock failed for %s\n", mas
);
152 /* Elided mutexes don't fail destroy, thus only test this if we don't assume
154 if (assume_elided_mutex
== false)
156 e
= pthread_mutex_destroy (m
);
159 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas
);
165 mutex_destroy of self-locked mutex did not return EBUSY %s\n",
171 if (pthread_mutex_unlock (m
) != 0)
173 printf ("1st mutex_unlock failed for %s\n", mas
);
177 if (pthread_mutex_trylock (m
) != 0)
179 printf ("mutex_trylock failed for %s\n", mas
);
183 /* Elided mutexes don't fail destroy. */
184 if (assume_elided_mutex
== false)
186 e
= pthread_mutex_destroy (m
);
189 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n",
196 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
202 if (pthread_mutex_unlock (m
) != 0)
204 printf ("2nd mutex_unlock failed for %s\n", mas
);
209 if (pthread_create (&th
, NULL
, tf
, NULL
) != 0)
211 puts ("1st create failed");
216 e
= pthread_barrier_wait (&b
);
217 if (e
!= 0 && e
!= PTHREAD_BARRIER_SERIAL_THREAD
)
219 puts ("1st barrier_wait failed");
223 if (pthread_mutex_lock (m
) != 0)
225 printf ("2nd mutex_lock failed for %s\n", mas
);
229 if (pthread_mutex_unlock (m
) != 0)
231 printf ("3rd mutex_unlock failed for %s\n", mas
);
235 /* Elided mutexes don't fail destroy. */
236 if (assume_elided_mutex
== false)
238 e
= pthread_mutex_destroy (m
);
241 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n",
248 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas
);
254 if (pthread_cond_signal (&c
) != 0)
256 puts ("cond_signal failed");
261 if (pthread_join (th
, &r
) != 0)
263 puts ("join failed");
268 puts ("thread didn't return NULL");
272 if (pthread_mutex_destroy (m
) != 0)
274 printf ("mutex_destroy after condvar-use failed for %s\n", mas
);
278 if (pthread_mutex_init (m
, ma
) != 0)
280 printf ("3rd mutex_init failed for %s\n", mas
);
284 if (pthread_create (&th
, NULL
, tf
, (void *) 1) != 0)
286 puts ("2nd create failed");
291 e
= pthread_barrier_wait (&b
);
292 if (e
!= 0 && e
!= PTHREAD_BARRIER_SERIAL_THREAD
)
294 puts ("2nd barrier_wait failed");
298 if (pthread_mutex_lock (m
) != 0)
300 printf ("3rd mutex_lock failed for %s\n", mas
);
304 if (pthread_mutex_unlock (m
) != 0)
306 printf ("4th mutex_unlock failed for %s\n", mas
);
310 /* Elided mutexes don't fail destroy. */
311 if (assume_elided_mutex
== false)
313 e
= pthread_mutex_destroy (m
);
316 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
323 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
329 if (pthread_cancel (th
) != 0)
331 puts ("cond_cancel failed");
335 if (pthread_join (th
, &r
) != 0)
337 puts ("join failed");
340 if (r
!= PTHREAD_CANCELED
)
342 puts ("thread not canceled");
346 if (pthread_mutex_destroy (m
) != 0)
348 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas
);
362 if (pthread_barrier_init (&b
, NULL
, 2) != 0)
364 puts ("barrier_init failed");
368 if (pthread_cond_init (&c
, NULL
) != 0)
370 puts ("cond_init failed");
374 puts ("check normal mutex");
375 int res
= check_type ("normal", NULL
);
377 pthread_mutexattr_t ma
;
378 if (pthread_mutexattr_init (&ma
) != 0)
380 puts ("1st mutexattr_init failed");
383 if (pthread_mutexattr_settype (&ma
, PTHREAD_MUTEX_RECURSIVE
) != 0)
385 puts ("1st mutexattr_settype failed");
389 if (pthread_mutexattr_setprotocol (&ma
, PTHREAD_PRIO_INHERIT
))
391 puts ("1st pthread_mutexattr_setprotocol failed");
395 puts ("check recursive mutex");
396 res
|= check_type ("recursive", &ma
);
397 if (pthread_mutexattr_destroy (&ma
) != 0)
399 puts ("1st mutexattr_destroy failed");
403 if (pthread_mutexattr_init (&ma
) != 0)
405 puts ("2nd mutexattr_init failed");
408 if (pthread_mutexattr_settype (&ma
, PTHREAD_MUTEX_ERRORCHECK
) != 0)
410 puts ("2nd mutexattr_settype failed");
414 if (pthread_mutexattr_setprotocol (&ma
, PTHREAD_PRIO_INHERIT
))
416 puts ("2nd pthread_mutexattr_setprotocol failed");
420 puts ("check error-checking mutex");
421 res
|= check_type ("error-checking", &ma
);
422 if (pthread_mutexattr_destroy (&ma
) != 0)
424 puts ("2nd mutexattr_destroy failed");
431 #define TEST_FUNCTION do_test ()
432 #include "../test-skeleton.c"