1 /* Verify that condition variables synchronized by PI mutexes don't hang on
3 Copyright (C) 2012 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"