1 /* Verify that condition variables synchronized by PI mutexes don't hang on
3 Copyright (C) 2012-2014 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
26 #include <sys/types.h>
27 #include <sys/syscall.h>
36 typedef void *(*thr_func) (void *);
38 pthread_mutex_t mutex;
41 void cleanup (void *u)
43 /* pthread_cond_wait should always return with the mutex locked. */
44 if (pthread_mutex_unlock (&mutex))
54 for (i = 0; i < ITERS; i++)
56 if ((ret = pthread_mutex_lock (&mutex)) != 0)
59 printf ("signaller:mutex_lock failed: %s\n", strerror (ret));
62 if ((ret = pthread_cond_signal (&cond)) != 0)
65 printf ("signaller:signal failed: %s\n", strerror (ret));
68 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
71 printf ("signaller:mutex_unlock failed: %s\n", strerror (ret));
74 pthread_testcancel ();
81 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
82 printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret));
91 int seq = (uintptr_t) u;
93 for (i = 0; i < ITERS / NUM; i++)
95 if ((ret = pthread_mutex_lock (&mutex)) != 0)
97 tret = (void *) (uintptr_t) 1;
98 printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
101 pthread_cleanup_push (cleanup, NULL);
103 if ((ret = pthread_cond_wait (&cond, &mutex)) != 0)
105 tret = (void *) (uintptr_t) 1;
106 printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret));
110 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
112 tret = (void *) (uintptr_t) 1;
113 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
116 pthread_cleanup_pop (0);
120 puts ("waiter tests done");
124 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
125 printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret));
130 timed_waiter (void *u)
134 int seq = (uintptr_t) u;
136 for (i = 0; i < ITERS / NUM; i++)
140 if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0)
142 tret = (void *) (uintptr_t) 1;
143 printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno));
148 if ((ret = pthread_mutex_lock (&mutex)) != 0)
150 tret = (void *) (uintptr_t) 1;
151 printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
154 pthread_cleanup_push (cleanup, NULL);
156 /* We should not time out either. */
157 if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0)
159 tret = (void *) (uintptr_t) 1;
160 printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret));
163 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
165 tret = (void *) (uintptr_t) 1;
166 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
169 pthread_cleanup_pop (0);
173 puts ("timed_waiter tests done");
177 if ((ret = pthread_mutex_unlock (&mutex)) != 0)
178 printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret));
183 do_test_wait (thr_func f)
187 pthread_mutexattr_t attr;
191 for (i = 0; i < COUNT; i++)
193 if ((ret = pthread_mutexattr_init (&attr)) != 0)
195 printf ("mutexattr_init failed: %s\n", strerror (ret));
199 if ((ret = pthread_mutexattr_setprotocol (&attr,
200 PTHREAD_PRIO_INHERIT)) != 0)
202 printf ("mutexattr_setprotocol failed: %s\n", strerror (ret));
206 if ((ret = pthread_cond_init (&cond, NULL)) != 0)
208 printf ("cond_init failed: %s\n", strerror (ret));
212 if ((ret = pthread_mutex_init (&mutex, &attr)) != 0)
214 printf ("mutex_init failed: %s\n", strerror (ret));
218 for (j = 0; j < NUM; j++)
219 if ((ret = pthread_create (&w[j], NULL,
220 f, (void *) (uintptr_t) j)) != 0)
222 printf ("waiter[%d]: create failed: %s\n", j, strerror (ret));
226 if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0)
228 printf ("signaller: create failed: %s\n", strerror (ret));
232 for (j = 0; j < NUM; j++)
234 pthread_cancel (w[j]);
236 if ((ret = pthread_join (w[j], &thr_ret)) != 0)
238 printf ("waiter[%d]: join failed: %s\n", j, strerror (ret));
242 if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
249 /* The signalling thread could have ended before it was cancelled. */
252 if ((ret = pthread_join (s, &thr_ret)) != 0)
254 printf ("signaller: join failed: %s\n", strerror (ret));
258 if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
270 do_test (int argc, char **argv)
272 int ret = do_test_wait (waiter);
277 return do_test_wait (timed_waiter);
281 #include "../test-skeleton.c"