1 diff -pruN glibc-2.12-2-gc4ccff1/nptl/Makefile glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile
2 --- glibc-2.12-2-gc4ccff1/nptl/Makefile 2013-07-09 10:18:22.267421846 +0530
3 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/Makefile 2013-07-09 10:16:22.043427519 +0530
4 @@ -207,7 +207,8 @@ tests = tst-typesizes \
5 tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
6 tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
7 tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
8 - tst-cond20 tst-cond21 tst-cond22 tst-cond23 \
9 + tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \
11 tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
12 tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
13 tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
14 @@ -275,6 +276,8 @@ gen-as-const-headers = pthread-errnos.sy
16 LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
18 +LDFLAGS-tst-cond24 = -lrt
19 +LDFLAGS-tst-cond25 = -lrt
23 diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
24 --- glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 2010-05-04 16:57:23.000000000 +0530
25 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 2013-07-09 10:16:22.044427519 +0530
26 @@ -203,9 +203,11 @@ __pthread_cond_timedwait:
29 addl $cond_futex, %ebx
33 subl $cond_futex, %ebx
36 /* Set the pi-requeued flag only if the kernel has returned 0. The
37 kernel does not hold the mutex on ETIMEDOUT or any other error. */
38 @@ -213,8 +215,23 @@ __pthread_cond_timedwait:
42 - /* Normal and PI futexes dont mix. Use normal futex functions only
43 - if the kernel does not support the PI futex functions. */
44 + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
45 + successfully, it has already locked the mutex for us and the
46 + pi_flag (24(%esp)) is set to denote that fact. However, if another
47 + thread changed the futex value before we entered the wait, the
48 + syscall may return an EAGAIN and the mutex is not locked. We go
49 + ahead with a success anyway since later we look at the pi_flag to
50 + decide if we got the mutex or not. The sequence numbers then make
51 + sure that only one of the threads actually wake up. We retry using
52 + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
53 + and PI futexes don't mix.
55 + Note that we don't check for EAGAIN specifically; we assume that the
56 + only other error the futex function could return is EAGAIN (barring
57 + the ETIMEOUT of course, for the timeout case in futex) since
58 + anything else would mean an error in our function. It is too
59 + expensive to do that check for every call (which is quite common in
60 + case of a large number of threads), so it has been skipped. */
64 @@ -274,9 +291,24 @@ __pthread_cond_timedwait:
67 15: cmpl $-ETIMEDOUT, %esi
71 - addl $1, wakeup_seq(%ebx)
72 + /* We need to go back to futex_wait. If we're using requeue_pi, then
73 + release the mutex we had acquired and go back. */
78 + /* Adjust the mutex values first and then unlock it. The unlock
79 + should always succeed or else the kernel did not lock the mutex
81 + movl dep_mutex(%ebx), %eax
82 + call __pthread_mutex_cond_lock_adjust
84 + call __pthread_mutex_unlock_usercnt
87 +28: addl $1, wakeup_seq(%ebx)
88 adcl $0, wakeup_seq+4(%ebx)
89 addl $1, cond_futex(%ebx)
91 @@ -644,10 +676,27 @@ __condvar_tw_cleanup:
92 movl $0x7fffffff, %edx
95 + /* Lock the mutex only if we don't own it already. This only happens
96 + in case of PI mutexes, if we got cancelled after a successful
97 + return of the futex syscall and before disabling async
99 5: movl 24+FRAME_SIZE(%esp), %eax
100 - call __pthread_mutex_cond_lock
101 + movl MUTEX_KIND(%eax), %ebx
102 + andl $(ROBUST_BIT|PI_BIT), %ebx
107 + andl $TID_MASK, %ebx
110 + /* We managed to get the lock. Fix it up before returning. */
111 + call __pthread_mutex_cond_lock_adjust
114 +8: call __pthread_mutex_cond_lock
117 +9: movl %esi, (%esp)
121 @@ -665,7 +714,15 @@ __condvar_tw_cleanup:
122 .uleb128 .Lcstend-.Lcstbegin
124 .long .LcleanupSTART-.LSTARTCODE
125 - .long .Ladd_cond_futex-.LcleanupSTART
126 + .long .Ladd_cond_futex_pi-.LcleanupSTART
127 + .long __condvar_tw_cleanup-.LSTARTCODE
129 + .long .Ladd_cond_futex_pi-.LSTARTCODE
130 + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
131 + .long __condvar_tw_cleanup2-.LSTARTCODE
133 + .long .Lsub_cond_futex_pi-.LSTARTCODE
134 + .long .Ladd_cond_futex-.Lsub_cond_futex_pi
135 .long __condvar_tw_cleanup-.LSTARTCODE
137 .long .Ladd_cond_futex-.LSTARTCODE
138 diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
139 --- glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S 2010-05-04 16:57:23.000000000 +0530
140 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S 2013-07-09 10:16:22.046427519 +0530
141 @@ -138,17 +138,33 @@ __pthread_cond_wait:
144 addl $cond_futex, %ebx
145 +.Ladd_cond_futex_pi:
146 movl $SYS_futex, %eax
148 subl $cond_futex, %ebx
149 +.Lsub_cond_futex_pi:
150 /* Set the pi-requeued flag only if the kernel has returned 0. The
151 kernel does not hold the mutex on error. */
156 - /* Normal and PI futexes dont mix. Use normal futex functions only
157 - if the kernel does not support the PI futex functions. */
158 + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
159 + successfully, it has already locked the mutex for us and the
160 + pi_flag (16(%esp)) is set to denote that fact. However, if another
161 + thread changed the futex value before we entered the wait, the
162 + syscall may return an EAGAIN and the mutex is not locked. We go
163 + ahead with a success anyway since later we look at the pi_flag to
164 + decide if we got the mutex or not. The sequence numbers then make
165 + sure that only one of the threads actually wake up. We retry using
166 + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
167 + and PI futexes don't mix.
169 + Note that we don't check for EAGAIN specifically; we assume that the
170 + only other error the futex function could return is EAGAIN since
171 + anything else would mean an error in our function. It is too
172 + expensive to do that check for every call (which is quite common in
173 + case of a large number of threads), so it has been skipped. */
177 @@ -198,12 +214,12 @@ __pthread_cond_wait:
190 9: addl $1, woken_seq(%ebx)
191 adcl $0, woken_seq+4(%ebx)
192 @@ -279,6 +295,22 @@ __pthread_cond_wait:
195 cfi_adjust_cfa_offset(-FRAME_SIZE);
197 + /* We need to go back to futex_wait. If we're using requeue_pi, then
198 + release the mutex we had acquired and go back. */
199 +22: movl 16(%esp), %edx
203 + /* Adjust the mutex values first and then unlock it. The unlock
204 + should always succeed or else the kernel did not lock the mutex
206 + movl dep_mutex(%ebx), %eax
207 + call __pthread_mutex_cond_lock_adjust
209 + call __pthread_mutex_unlock_usercnt
212 /* Initial locking failed. */
215 @@ -391,6 +423,7 @@ __pthread_cond_wait:
217 call __lll_unlock_wake
220 .size __pthread_cond_wait, .-__pthread_cond_wait
221 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
223 @@ -531,10 +564,27 @@ __condvar_w_cleanup:
224 movl $0x7fffffff, %edx
227 + /* Lock the mutex only if we don't own it already. This only happens
228 + in case of PI mutexes, if we got cancelled after a successful
229 + return of the futex syscall and before disabling async
231 5: movl 24+FRAME_SIZE(%esp), %eax
232 - call __pthread_mutex_cond_lock
233 + movl MUTEX_KIND(%eax), %ebx
234 + andl $(ROBUST_BIT|PI_BIT), %ebx
239 + andl $TID_MASK, %ebx
242 + /* We managed to get the lock. Fix it up before returning. */
243 + call __pthread_mutex_cond_lock_adjust
247 +8: call __pthread_mutex_cond_lock
249 +9: movl %esi, (%esp)
253 @@ -552,7 +602,15 @@ __condvar_w_cleanup:
254 .uleb128 .Lcstend-.Lcstbegin
256 .long .LcleanupSTART-.LSTARTCODE
257 - .long .Ladd_cond_futex-.LcleanupSTART
258 + .long .Ladd_cond_futex_pi-.LcleanupSTART
259 + .long __condvar_w_cleanup-.LSTARTCODE
261 + .long .Ladd_cond_futex_pi-.LSTARTCODE
262 + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
263 + .long __condvar_w_cleanup2-.LSTARTCODE
265 + .long .Lsub_cond_futex_pi-.LSTARTCODE
266 + .long .Ladd_cond_futex-.Lsub_cond_futex_pi
267 .long __condvar_w_cleanup-.LSTARTCODE
269 .long .Ladd_cond_futex-.LSTARTCODE
270 diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
271 --- glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym 2010-05-04 16:57:23.000000000 +0530
272 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym 2013-07-09 10:16:22.047427519 +0530
273 @@ -6,3 +6,4 @@ MUTEX_KIND offsetof (pthread_mutex_t, __
274 ROBUST_BIT PTHREAD_MUTEX_ROBUST_NORMAL_NP
275 PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP
276 PS_BIT PTHREAD_MUTEX_PSHARED_BIT
277 +TID_MASK FUTEX_TID_MASK
278 diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
279 --- glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S 2013-07-09 10:18:22.506421835 +0530
280 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S 2013-07-09 10:16:22.048427519 +0530
281 @@ -104,6 +104,8 @@ __pthread_cond_timedwait:
282 movq %rsi, dep_mutex(%rdi)
287 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
289 cmpl $0, __have_futex_clock_realtime(%rip)
290 @@ -189,18 +191,39 @@ __pthread_cond_timedwait:
291 movl $SYS_futex, %eax
298 #ifdef __ASSUME_REQUEUE_PI
305 + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
306 + successfully, it has already locked the mutex for us and the
307 + pi_flag (%r15b) is set to denote that fact. However, if another
308 + thread changed the futex value before we entered the wait, the
309 + syscall may return an EAGAIN and the mutex is not locked. We go
310 + ahead with a success anyway since later we look at the pi_flag to
311 + decide if we got the mutex or not. The sequence numbers then make
312 + sure that only one of the threads actually wake up. We retry using
313 + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
314 + and PI futexes don't mix.
316 + Note that we don't check for EAGAIN specifically; we assume that the
317 + only other error the futex function could return is EAGAIN (barring
318 + the ETIMEOUT of course, for the timeout case in futex) since
319 + anything else would mean an error in our function. It is too
320 + expensive to do that check for every call (which is quite common in
321 + case of a large number of threads), so it has been skipped. */
322 + cmpl $-ENOSYS, %eax
325 subq $cond_futex, %rdi
328 61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
329 -60: xorl %r15d, %r15d
330 +60: xorb %r15b, %r15b
332 /* The following only works like this because we only support
333 two clocks, represented using a single bit. */
334 @@ -247,7 +270,23 @@ __pthread_cond_timedwait:
337 45: cmpq $-ETIMEDOUT, %r14
341 + /* We need to go back to futex_wait. If we're using requeue_pi, then
342 + release the mutex we had acquired and go back. */
346 + /* Adjust the mutex values first and then unlock it. The unlock
347 + should always succeed or else the kernel did not lock the
348 + mutex correctly. */
350 + callq __pthread_mutex_cond_lock_adjust
352 + callq __pthread_mutex_unlock_usercnt
353 + /* Reload cond_var. */
357 99: incq wakeup_seq(%rdi)
358 incl cond_futex(%rdi)
359 @@ -297,7 +336,7 @@ __pthread_cond_timedwait:
360 /* If requeue_pi is used the kernel performs the locking of the
362 41: movq 16(%rsp), %rdi
367 callq __pthread_mutex_cond_lock
368 @@ -405,8 +444,6 @@ __pthread_cond_timedwait:
370 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
374 /* Get internal lock. */
377 @@ -765,10 +802,27 @@ __condvar_cleanup2:
378 movl $SYS_futex, %eax
381 + /* Lock the mutex only if we don't own it already. This only happens
382 + in case of PI mutexes, if we got cancelled after a successful
383 + return of the futex syscall and before disabling async
385 5: movq 16(%rsp), %rdi
386 - callq __pthread_mutex_cond_lock
387 + movl MUTEX_KIND(%rdi), %eax
388 + andl $(ROBUST_BIT|PI_BIT), %eax
393 + andl $TID_MASK, %eax
396 + /* We managed to get the lock. Fix it up before returning. */
397 + callq __pthread_mutex_cond_lock_adjust
400 +7: callq __pthread_mutex_cond_lock
402 - movq 24(%rsp), %rdi
403 +8: movq 24(%rsp), %rdi
404 movq FRAME_SIZE(%rsp), %r15
405 movq FRAME_SIZE+8(%rsp), %r14
406 movq FRAME_SIZE+16(%rsp), %r13
407 diff -pruN glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
408 --- glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S 2013-07-09 10:18:22.507421834 +0530
409 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S 2013-07-09 10:16:22.048427519 +0530
411 #include <lowlevelcond.h>
412 #include <tcb-offsets.h>
413 #include <pthread-pi-defines.h>
414 +#include <pthread-errnos.h>
416 #include <kernel-features.h>
418 @@ -137,12 +138,32 @@ __pthread_cond_wait:
419 movl $SYS_futex, %eax
426 #ifdef __ASSUME_REQUEUE_PI
433 + /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
434 + successfully, it has already locked the mutex for us and the
435 + pi_flag (%r8b) is set to denote that fact. However, if another
436 + thread changed the futex value before we entered the wait, the
437 + syscall may return an EAGAIN and the mutex is not locked. We go
438 + ahead with a success anyway since later we look at the pi_flag to
439 + decide if we got the mutex or not. The sequence numbers then make
440 + sure that only one of the threads actually wake up. We retry using
441 + normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
442 + and PI futexes don't mix.
444 + Note that we don't check for EAGAIN specifically; we assume that the
445 + only other error the futex function could return is EAGAIN since
446 + anything else would mean an error in our function. It is too
447 + expensive to do that check for every call (which is quite common in
448 + case of a large number of threads), so it has been skipped. */
449 + cmpl $-ENOSYS, %eax
452 # ifndef __ASSUME_PRIVATE_FUTEX
453 movl $FUTEX_WAIT, %esi
454 @@ -155,7 +176,7 @@ __pthread_cond_wait:
456 orl %fs:PRIVATE_FUTEX, %esi
460 movl $SYS_futex, %eax
463 @@ -185,10 +206,10 @@ __pthread_cond_wait:
476 @@ -230,7 +251,7 @@ __pthread_cond_wait:
477 /* If requeue_pi is used the kernel performs the locking of the
479 11: movq 16(%rsp), %rdi
484 callq __pthread_mutex_cond_lock
485 @@ -247,6 +268,23 @@ __pthread_cond_wait:
489 + /* We need to go back to futex_wait. If we're using requeue_pi, then
490 + release the mutex we had acquired and go back. */
491 +19: testb %r8b, %r8b
494 + /* Adjust the mutex values first and then unlock it. The unlock
495 + should always succeed or else the kernel did not lock the mutex
497 + movq 16(%rsp), %rdi
498 + callq __pthread_mutex_cond_lock_adjust
501 + callq __pthread_mutex_unlock_usercnt
502 + /* Reload cond_var. */
506 /* Initial locking failed. */
509 @@ -324,6 +362,7 @@ __pthread_cond_wait:
514 .size __pthread_cond_wait, .-__pthread_cond_wait
515 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
517 @@ -454,10 +493,28 @@ __condvar_cleanup1:
518 movl $SYS_futex, %eax
521 + /* Lock the mutex only if we don't own it already. This only happens
522 + in case of PI mutexes, if we got cancelled after a successful
523 + return of the futex syscall and before disabling async
525 5: movq 16(%rsp), %rdi
526 - callq __pthread_mutex_cond_lock
527 + movl MUTEX_KIND(%rdi), %eax
528 + andl $(ROBUST_BIT|PI_BIT), %eax
533 + andl $TID_MASK, %eax
536 + /* We managed to get the lock. Fix it up before returning. */
537 + callq __pthread_mutex_cond_lock_adjust
541 - movq 24(%rsp), %rdi
542 +7: callq __pthread_mutex_cond_lock
544 +8: movq 24(%rsp), %rdi
546 call _Unwind_Resume@PLT
548 @@ -476,11 +533,11 @@ __condvar_cleanup1:
549 .uleb128 .LcleanupSTART-.LSTARTCODE
550 .uleb128 .LcleanupEND-.LcleanupSTART
551 .uleb128 __condvar_cleanup1-.LSTARTCODE
554 .uleb128 .LcallUR-.LSTARTCODE
555 .uleb128 .LENDCODE-.LcallUR
562 diff -pruN glibc-2.12-2-gc4ccff1/nptl/tst-cond24.c glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond24.c
563 --- glibc-2.12-2-gc4ccff1/nptl/tst-cond24.c 1970-01-01 05:30:00.000000000 +0530
564 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond24.c 2013-07-09 10:19:10.008419593 +0530
566 +/* Verify that condition variables synchronized by PI mutexes don't hang.
567 + Copyright (C) 2012-2013 Free Software Foundation, Inc.
568 + This file is part of the GNU C Library.
570 + The GNU C Library is free software; you can redistribute it and/or
571 + modify it under the terms of the GNU Lesser General Public
572 + License as published by the Free Software Foundation; either
573 + version 2.1 of the License, or (at your option) any later version.
575 + The GNU C Library is distributed in the hope that it will be useful,
576 + but WITHOUT ANY WARRANTY; without even the implied warranty of
577 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
578 + Lesser General Public License for more details.
580 + You should have received a copy of the GNU Lesser General Public
581 + License along with the GNU C Library; if not, see
582 + <http://www.gnu.org/licenses/>. */
584 +#include <pthread.h>
589 +#include <sys/types.h>
590 +#include <sys/syscall.h>
592 +#include <sys/time.h>
595 +#define THREADS_NUM 5
596 +#define MAXITER 50000
598 +static pthread_mutex_t mutex;
599 +static pthread_mutexattr_t mutex_attr;
600 +static pthread_cond_t cond;
601 +static pthread_t threads[THREADS_NUM];
602 +static int pending = 0;
604 +typedef void * (*threadfunc) (void *);
607 +thread_fun_timed (void *arg)
612 + printf ("Started thread_fun_timed[%d]\n", *ret);
614 + for (i = 0; i < MAXITER / THREADS_NUM; i++)
616 + rv = pthread_mutex_lock (&mutex);
619 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
626 + struct timespec ts;
627 + clock_gettime(CLOCK_REALTIME, &ts);
629 + rv = pthread_cond_timedwait (&cond, &mutex, &ts);
631 + /* There should be no timeout either. */
634 + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
642 + rv = pthread_mutex_unlock (&mutex);
645 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
658 +thread_fun (void *arg)
663 + printf ("Started thread_fun[%d]\n", *ret);
665 + for (i = 0; i < MAXITER / THREADS_NUM; i++)
667 + rv = pthread_mutex_lock (&mutex);
670 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
677 + rv = pthread_cond_wait (&cond, &mutex);
681 + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
689 + rv = pthread_mutex_unlock (&mutex);
692 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
705 +do_test_wait (threadfunc f)
710 + int retval[THREADS_NUM];
712 + puts ("Starting test");
714 + rv = pthread_mutexattr_init (&mutex_attr);
717 + printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv);
721 + rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT);
724 + printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv);
728 + rv = pthread_mutex_init (&mutex, &mutex_attr);
731 + printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv);
735 + rv = pthread_cond_init (&cond, NULL);
738 + printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv);
742 + for (i = 0; i < THREADS_NUM; i++)
745 + rv = pthread_create (&threads[i], NULL, f, &retval[i]);
748 + printf ("pthread_create: %s(%d)\n", strerror (rv), rv);
753 + for (; counter < MAXITER; counter++)
755 + rv = pthread_mutex_lock (&mutex);
758 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
762 + if (!(counter % 100))
763 + printf ("counter: %d\n", counter);
766 + rv = pthread_cond_signal (&cond);
769 + printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv);
773 + rv = pthread_mutex_unlock (&mutex);
776 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
781 + for (i = 0; i < THREADS_NUM; i++)
784 + rv = pthread_join (threads[i], &ret);
787 + printf ("pthread_join: %s(%d)\n", strerror (rv), rv);
790 + if (ret && *(int *)ret)
792 + printf ("Thread %d returned with an error\n", i);
803 + puts ("Testing pthread_cond_wait");
804 + int ret = do_test_wait (thread_fun);
808 + puts ("Testing pthread_cond_timedwait");
809 + return do_test_wait (thread_fun_timed);
813 +#define TEST_FUNCTION do_test ()
814 +#include "../test-skeleton.c"
815 diff -pruN glibc-2.12-2-gc4ccff1/nptl/tst-cond25.c glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond25.c
816 --- glibc-2.12-2-gc4ccff1/nptl/tst-cond25.c 1970-01-01 05:30:00.000000000 +0530
817 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond25.c 2013-07-09 10:19:15.472419335 +0530
819 +/* Verify that condition variables synchronized by PI mutexes don't hang on
821 + Copyright (C) 2012-2013 Free Software Foundation, Inc.
822 + This file is part of the GNU C Library.
824 + The GNU C Library is free software; you can redistribute it and/or
825 + modify it under the terms of the GNU Lesser General Public
826 + License as published by the Free Software Foundation; either
827 + version 2.1 of the License, or (at your option) any later version.
829 + The GNU C Library is distributed in the hope that it will be useful,
830 + but WITHOUT ANY WARRANTY; without even the implied warranty of
831 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
832 + Lesser General Public License for more details.
834 + You should have received a copy of the GNU Lesser General Public
835 + License along with the GNU C Library; if not, see
836 + <http://www.gnu.org/licenses/>. */
838 +#include <pthread.h>
844 +#include <sys/types.h>
845 +#include <sys/syscall.h>
847 +#include <sys/time.h>
854 +typedef void *(*thr_func) (void *);
856 +pthread_mutex_t mutex;
857 +pthread_cond_t cond;
859 +void cleanup (void *u)
861 + /* pthread_cond_wait should always return with the mutex locked. */
862 + if (pthread_mutex_unlock (&mutex))
872 + for (i = 0; i < ITERS; i++)
874 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
877 + printf ("signaller:mutex_lock failed: %s\n", strerror (ret));
880 + if ((ret = pthread_cond_signal (&cond)) != 0)
883 + printf ("signaller:signal failed: %s\n", strerror (ret));
886 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
889 + printf ("signaller:mutex_unlock failed: %s\n", strerror (ret));
892 + pthread_testcancel ();
899 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
900 + printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret));
909 + int seq = (uintptr_t) u;
911 + for (i = 0; i < ITERS / NUM; i++)
913 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
915 + tret = (void *) (uintptr_t) 1;
916 + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
919 + pthread_cleanup_push (cleanup, NULL);
921 + if ((ret = pthread_cond_wait (&cond, &mutex)) != 0)
923 + tret = (void *) (uintptr_t) 1;
924 + printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret));
928 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
930 + tret = (void *) (uintptr_t) 1;
931 + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
934 + pthread_cleanup_pop (0);
938 + puts ("waiter tests done");
942 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
943 + printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret));
948 +timed_waiter (void *u)
952 + int seq = (uintptr_t) u;
954 + for (i = 0; i < ITERS / NUM; i++)
956 + struct timespec ts;
958 + if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0)
960 + tret = (void *) (uintptr_t) 1;
961 + printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno));
966 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
968 + tret = (void *) (uintptr_t) 1;
969 + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
972 + pthread_cleanup_push (cleanup, NULL);
974 + /* We should not time out either. */
975 + if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0)
977 + tret = (void *) (uintptr_t) 1;
978 + printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret));
981 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
983 + tret = (void *) (uintptr_t) 1;
984 + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
987 + pthread_cleanup_pop (0);
991 + puts ("timed_waiter tests done");
995 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
996 + printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret));
1001 +do_test_wait (thr_func f)
1005 + pthread_mutexattr_t attr;
1006 + int i, j, ret = 0;
1009 + for (i = 0; i < COUNT; i++)
1011 + if ((ret = pthread_mutexattr_init (&attr)) != 0)
1013 + printf ("mutexattr_init failed: %s\n", strerror (ret));
1017 + if ((ret = pthread_mutexattr_setprotocol (&attr,
1018 + PTHREAD_PRIO_INHERIT)) != 0)
1020 + printf ("mutexattr_setprotocol failed: %s\n", strerror (ret));
1024 + if ((ret = pthread_cond_init (&cond, NULL)) != 0)
1026 + printf ("cond_init failed: %s\n", strerror (ret));
1030 + if ((ret = pthread_mutex_init (&mutex, &attr)) != 0)
1032 + printf ("mutex_init failed: %s\n", strerror (ret));
1036 + for (j = 0; j < NUM; j++)
1037 + if ((ret = pthread_create (&w[j], NULL,
1038 + f, (void *) (uintptr_t) j)) != 0)
1040 + printf ("waiter[%d]: create failed: %s\n", j, strerror (ret));
1044 + if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0)
1046 + printf ("signaller: create failed: %s\n", strerror (ret));
1050 + for (j = 0; j < NUM; j++)
1052 + pthread_cancel (w[j]);
1054 + if ((ret = pthread_join (w[j], &thr_ret)) != 0)
1056 + printf ("waiter[%d]: join failed: %s\n", j, strerror (ret));
1060 + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
1067 + /* The signalling thread could have ended before it was cancelled. */
1068 + pthread_cancel (s);
1070 + if ((ret = pthread_join (s, &thr_ret)) != 0)
1072 + printf ("signaller: join failed: %s\n", strerror (ret));
1076 + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
1088 +do_test (int argc, char **argv)
1090 + int ret = do_test_wait (waiter);
1095 + return do_test_wait (timed_waiter);
1099 +#include "../test-skeleton.c"
1100 diff -pruN glibc-2.12-2-gc4ccff1/nptl/tst-cond-except.c glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond-except.c
1101 --- glibc-2.12-2-gc4ccff1/nptl/tst-cond-except.c 1970-01-01 05:30:00.000000000 +0530
1102 +++ glibc-2.12-2-gc4ccff1.fixed/nptl/tst-cond-except.c 2013-07-09 10:19:01.334420002 +0530
1104 +/* Verify that exception table for pthread_cond_wait is correct.
1105 + Copyright (C) 2012-2013 Free Software Foundation, Inc.
1106 + This file is part of the GNU C Library.
1108 + The GNU C Library is free software; you can redistribute it and/or
1109 + modify it under the terms of the GNU Lesser General Public
1110 + License as published by the Free Software Foundation; either
1111 + version 2.1 of the License, or (at your option) any later version.
1113 + The GNU C Library is distributed in the hope that it will be useful,
1114 + but WITHOUT ANY WARRANTY; without even the implied warranty of
1115 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1116 + Lesser General Public License for more details.
1118 + You should have received a copy of the GNU Lesser General Public
1119 + License along with the GNU C Library; if not, see
1120 + <http://www.gnu.org/licenses/>. */
1122 +#include <pthread.h>
1124 +#include <stdint.h>
1125 +#include <string.h>
1126 +#include <unistd.h>
1128 +pthread_mutex_t mutex;
1129 +pthread_cond_t cond;
1131 +#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \
1132 + ({ if ((ret) != 0) \
1134 + printf ("%s failed: %s\n", (str), strerror (ret)); \
1144 + puts ("clean: Unlocking mutex...");
1145 + pthread_mutex_unlock ((pthread_mutex_t *) arg);
1146 + puts ("clean: Mutex unlocked...");
1153 + pthread_mutexattr_t mutexAttr;
1154 + ret = pthread_mutexattr_init (&mutexAttr);
1155 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init");
1157 + ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT);
1158 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol");
1160 + ret = pthread_mutex_init (&mutex, &mutexAttr);
1161 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init");
1163 + ret = pthread_cond_init (&cond, 0);
1164 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init");
1166 + puts ("th: Init done, entering wait...");
1168 + pthread_cleanup_push (clean, (void *) &mutex);
1169 + ret = pthread_mutex_lock (&mutex);
1170 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock");
1173 + ret = pthread_cond_wait (&cond, &mutex);
1174 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait");
1176 + pthread_cleanup_pop (1);
1179 + return (void *) (uintptr_t) ret;
1187 + void *thr_ret = 0;
1188 + ret = pthread_create (&thread, 0, thr, &thr_ret);
1189 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create");
1191 + puts ("main: Thread created, waiting a bit...");
1194 + puts ("main: Cancelling thread...");
1195 + ret = pthread_cancel (thread);
1196 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel");
1198 + puts ("main: Joining th...");
1199 + ret = pthread_join (thread, NULL);
1200 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join");
1202 + if (thr_ret != NULL)
1205 + puts ("main: Joined thread, done!");
1211 +#define TEST_FUNCTION do_test ()
1213 +#include "../test-skeleton.c"