1 /* Verify that condition variables synchronized by PI mutexes don't hang on
3 Copyright (C) 2012-2017 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. The
44 pthread_mutex_unlock implementation does not actually check whether we
45 own the mutex for several mutex kinds, so check this explicitly. */
46 int ret
= pthread_mutex_trylock (&mutex
);
47 if (ret
!= EDEADLK
&& ret
!= EBUSY
)
49 printf ("mutex not locked in cleanup %d\n", ret
);
52 if (pthread_mutex_unlock (&mutex
))
62 for (i
= 0; i
< ITERS
; i
++)
64 if ((ret
= pthread_mutex_lock (&mutex
)) != 0)
67 printf ("signaller:mutex_lock failed: %s\n", strerror (ret
));
70 if ((ret
= pthread_cond_signal (&cond
)) != 0)
73 printf ("signaller:signal failed: %s\n", strerror (ret
));
76 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
79 printf ("signaller:mutex_unlock failed: %s\n", strerror (ret
));
82 pthread_testcancel ();
89 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
90 printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret
));
99 int seq
= (uintptr_t) u
;
101 for (i
= 0; i
< ITERS
/ NUM
; i
++)
103 if ((ret
= pthread_mutex_lock (&mutex
)) != 0)
105 tret
= (void *) (uintptr_t) 1;
106 printf ("waiter[%u]:mutex_lock failed: %s\n", seq
, strerror (ret
));
109 pthread_cleanup_push (cleanup
, NULL
);
111 if ((ret
= pthread_cond_wait (&cond
, &mutex
)) != 0)
113 tret
= (void *) (uintptr_t) 1;
114 printf ("waiter[%u]:wait failed: %s\n", seq
, strerror (ret
));
118 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
120 tret
= (void *) (uintptr_t) 1;
121 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq
, strerror (ret
));
124 pthread_cleanup_pop (0);
128 puts ("waiter tests done");
132 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
133 printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret
));
138 timed_waiter (void *u
)
142 int seq
= (uintptr_t) u
;
144 for (i
= 0; i
< ITERS
/ NUM
; i
++)
148 if ((ret
= clock_gettime(CLOCK_REALTIME
, &ts
)) != 0)
150 tret
= (void *) (uintptr_t) 1;
151 printf ("%u:clock_gettime failed: %s\n", seq
, strerror (errno
));
156 if ((ret
= pthread_mutex_lock (&mutex
)) != 0)
158 tret
= (void *) (uintptr_t) 1;
159 printf ("waiter[%u]:mutex_lock failed: %s\n", seq
, strerror (ret
));
162 pthread_cleanup_push (cleanup
, NULL
);
164 /* We should not time out either. */
165 if ((ret
= pthread_cond_timedwait (&cond
, &mutex
, &ts
)) != 0)
167 tret
= (void *) (uintptr_t) 1;
168 printf ("waiter[%u]:timedwait failed: %s\n", seq
, strerror (ret
));
171 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
173 tret
= (void *) (uintptr_t) 1;
174 printf ("waiter[%u]:mutex_unlock failed: %s\n", seq
, strerror (ret
));
177 pthread_cleanup_pop (0);
181 puts ("timed_waiter tests done");
185 if ((ret
= pthread_mutex_unlock (&mutex
)) != 0)
186 printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq
, strerror (ret
));
191 do_test_wait (thr_func f
)
195 pthread_mutexattr_t attr
;
199 for (i
= 0; i
< COUNT
; i
++)
201 if ((ret
= pthread_mutexattr_init (&attr
)) != 0)
203 printf ("mutexattr_init failed: %s\n", strerror (ret
));
207 if ((ret
= pthread_mutexattr_setprotocol (&attr
,
208 PTHREAD_PRIO_INHERIT
)) != 0)
210 printf ("mutexattr_setprotocol failed: %s\n", strerror (ret
));
214 if ((ret
= pthread_cond_init (&cond
, NULL
)) != 0)
216 printf ("cond_init failed: %s\n", strerror (ret
));
220 if ((ret
= pthread_mutex_init (&mutex
, &attr
)) != 0)
222 printf ("mutex_init failed: %s\n", strerror (ret
));
226 for (j
= 0; j
< NUM
; j
++)
227 if ((ret
= pthread_create (&w
[j
], NULL
,
228 f
, (void *) (uintptr_t) j
)) != 0)
230 printf ("waiter[%d]: create failed: %s\n", j
, strerror (ret
));
234 if ((ret
= pthread_create (&s
, NULL
, signaller
, NULL
)) != 0)
236 printf ("signaller: create failed: %s\n", strerror (ret
));
240 for (j
= 0; j
< NUM
; j
++)
242 pthread_cancel (w
[j
]);
244 if ((ret
= pthread_join (w
[j
], &thr_ret
)) != 0)
246 printf ("waiter[%d]: join failed: %s\n", j
, strerror (ret
));
250 if (thr_ret
!= NULL
&& thr_ret
!= PTHREAD_CANCELED
)
257 /* The signalling thread could have ended before it was cancelled. */
260 if ((ret
= pthread_join (s
, &thr_ret
)) != 0)
262 printf ("signaller: join failed: %s\n", strerror (ret
));
266 if (thr_ret
!= NULL
&& thr_ret
!= PTHREAD_CANCELED
)
278 do_test (int argc
, char **argv
)
280 int ret
= do_test_wait (waiter
);
285 return do_test_wait (timed_waiter
);
289 #include "../test-skeleton.c"