]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/glibc/glibc-rh552960.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh552960.patch
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 \
10 + tst-cond-except \
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
15
16 LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
17
18 +LDFLAGS-tst-cond24 = -lrt
19 +LDFLAGS-tst-cond25 = -lrt
20
21 include ../Makeconfig
22
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:
27 42: leal (%ebp), %esi
28 movl 28(%esp), %edx
29 addl $cond_futex, %ebx
30 +.Ladd_cond_futex_pi:
31 movl $SYS_futex, %eax
32 ENTER_KERNEL
33 subl $cond_futex, %ebx
34 +.Lsub_cond_futex_pi:
35 movl %eax, %esi
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:
39 sete 24(%esp)
40 je 41f
41
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.
54 +
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. */
61 cmpl $-ENOSYS, %eax
62 jne 41f
63 xorl %ecx, %ecx
64 @@ -274,9 +291,24 @@ __pthread_cond_timedwait:
65 jne 9f
66
67 15: cmpl $-ETIMEDOUT, %esi
68 - jne 8b
69 + je 28f
70
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. */
74 + movl 24(%esp), %edx
75 + test %edx, %edx
76 + jz 8b
77 +
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
80 + correctly. */
81 + movl dep_mutex(%ebx), %eax
82 + call __pthread_mutex_cond_lock_adjust
83 + xorl %edx, %edx
84 + call __pthread_mutex_unlock_usercnt
85 + jmp 8b
86 +
87 +28: addl $1, wakeup_seq(%ebx)
88 adcl $0, wakeup_seq+4(%ebx)
89 addl $1, cond_futex(%ebx)
90 movl $ETIMEDOUT, %esi
91 @@ -644,10 +676,27 @@ __condvar_tw_cleanup:
92 movl $0x7fffffff, %edx
93 ENTER_KERNEL
94
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
98 + cancellation. */
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
103 + cmpl $PI_BIT, %ebx
104 + jne 8f
105 +
106 + movl (%eax), %ebx
107 + andl $TID_MASK, %ebx
108 + cmpl %ebx, %gs:TID
109 + jne 8f
110 + /* We managed to get the lock. Fix it up before returning. */
111 + call __pthread_mutex_cond_lock_adjust
112 + jmp 9f
113 +
114 +8: call __pthread_mutex_cond_lock
115
116 - movl %esi, (%esp)
117 +9: movl %esi, (%esp)
118 .LcallUR:
119 call _Unwind_Resume
120 hlt
121 @@ -665,7 +714,15 @@ __condvar_tw_cleanup:
122 .uleb128 .Lcstend-.Lcstbegin
123 .Lcstbegin:
124 .long .LcleanupSTART-.LSTARTCODE
125 - .long .Ladd_cond_futex-.LcleanupSTART
126 + .long .Ladd_cond_futex_pi-.LcleanupSTART
127 + .long __condvar_tw_cleanup-.LSTARTCODE
128 + .uleb128 0
129 + .long .Ladd_cond_futex_pi-.LSTARTCODE
130 + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
131 + .long __condvar_tw_cleanup2-.LSTARTCODE
132 + .uleb128 0
133 + .long .Lsub_cond_futex_pi-.LSTARTCODE
134 + .long .Ladd_cond_futex-.Lsub_cond_futex_pi
135 .long __condvar_tw_cleanup-.LSTARTCODE
136 .uleb128 0
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:
142 movl %ebp, %edx
143 xorl %esi, %esi
144 addl $cond_futex, %ebx
145 +.Ladd_cond_futex_pi:
146 movl $SYS_futex, %eax
147 ENTER_KERNEL
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. */
152 cmpl $0, %eax
153 sete 16(%esp)
154 je 19f
155
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.
168 +
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. */
174 cmpl $-ENOSYS, %eax
175 jne 19f
176 xorl %ecx, %ecx
177 @@ -198,12 +214,12 @@ __pthread_cond_wait:
178 cmpl 8(%esp), %edx
179 jne 7f
180 cmpl 4(%esp), %edi
181 - je 8b
182 + je 22f
183
184 7: cmpl %ecx, %edx
185 jne 9f
186 cmp %eax, %edi
187 - je 8b
188 + je 22f
189
190 9: addl $1, woken_seq(%ebx)
191 adcl $0, woken_seq+4(%ebx)
192 @@ -279,6 +295,22 @@ __pthread_cond_wait:
193 jmp 20b
194
195 cfi_adjust_cfa_offset(-FRAME_SIZE);
196 +
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
200 + test %edx, %edx
201 + jz 8b
202 +
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
205 + correctly. */
206 + movl dep_mutex(%ebx), %eax
207 + call __pthread_mutex_cond_lock_adjust
208 + xorl %edx, %edx
209 + call __pthread_mutex_unlock_usercnt
210 + jmp 8b
211 +
212 /* Initial locking failed. */
213 1:
214 #if cond_lock == 0
215 @@ -391,6 +423,7 @@ __pthread_cond_wait:
216 #endif
217 call __lll_unlock_wake
218 jmp 11b
219 +
220 .size __pthread_cond_wait, .-__pthread_cond_wait
221 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
222 GLIBC_2_3_2)
223 @@ -531,10 +564,27 @@ __condvar_w_cleanup:
224 movl $0x7fffffff, %edx
225 ENTER_KERNEL
226
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
230 + cancellation. */
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
235 + cmpl $PI_BIT, %ebx
236 + jne 8f
237 +
238 + movl (%eax), %ebx
239 + andl $TID_MASK, %ebx
240 + cmpl %ebx, %gs:TID
241 + jne 8f
242 + /* We managed to get the lock. Fix it up before returning. */
243 + call __pthread_mutex_cond_lock_adjust
244 + jmp 9f
245
246 - movl %esi, (%esp)
247 +8: call __pthread_mutex_cond_lock
248 +
249 +9: movl %esi, (%esp)
250 .LcallUR:
251 call _Unwind_Resume
252 hlt
253 @@ -552,7 +602,15 @@ __condvar_w_cleanup:
254 .uleb128 .Lcstend-.Lcstbegin
255 .Lcstbegin:
256 .long .LcleanupSTART-.LSTARTCODE
257 - .long .Ladd_cond_futex-.LcleanupSTART
258 + .long .Ladd_cond_futex_pi-.LcleanupSTART
259 + .long __condvar_w_cleanup-.LSTARTCODE
260 + .uleb128 0
261 + .long .Ladd_cond_futex_pi-.LSTARTCODE
262 + .long .Lsub_cond_futex_pi-.Ladd_cond_futex_pi
263 + .long __condvar_w_cleanup2-.LSTARTCODE
264 + .uleb128 0
265 + .long .Lsub_cond_futex_pi-.LSTARTCODE
266 + .long .Ladd_cond_futex-.Lsub_cond_futex_pi
267 .long __condvar_w_cleanup-.LSTARTCODE
268 .uleb128 0
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)
283
284 22:
285 + xorb %r15b, %r15b
286 +
287 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
288 # ifdef PIC
289 cmpl $0, __have_futex_clock_realtime(%rip)
290 @@ -189,18 +191,39 @@ __pthread_cond_timedwait:
291 movl $SYS_futex, %eax
292 syscall
293
294 - movl $1, %r15d
295 + cmpl $0, %eax
296 + sete %r15b
297 +
298 #ifdef __ASSUME_REQUEUE_PI
299 jmp 62f
300 #else
301 - cmpq $-4095, %rax
302 - jnae 62f
303 + je 62f
304 +
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.
315 +
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
323 + jne 62f
324
325 subq $cond_futex, %rdi
326 #endif
327
328 61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
329 -60: xorl %r15d, %r15d
330 +60: xorb %r15b, %r15b
331 xorl %eax, %eax
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:
335 ja 39f
336
337 45: cmpq $-ETIMEDOUT, %r14
338 - jne 38b
339 + je 99f
340 +
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. */
343 + test %r15b, %r15b
344 + jz 38b
345 +
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. */
349 + movq %r8, %rdi
350 + callq __pthread_mutex_cond_lock_adjust
351 + xorl %esi, %esi
352 + callq __pthread_mutex_unlock_usercnt
353 + /* Reload cond_var. */
354 + movq 8(%rsp), %rdi
355 + jmp 38b
356
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
361 mutex. */
362 41: movq 16(%rsp), %rdi
363 - testl %r15d, %r15d
364 + testb %r15b, %r15b
365 jnz 64f
366
367 callq __pthread_mutex_cond_lock
368 @@ -405,8 +444,6 @@ __pthread_cond_timedwait:
369
370 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
371 .Lreltmo:
372 - xorl %r15d, %r15d
373 -
374 /* Get internal lock. */
375 movl $1, %esi
376 xorl %eax, %eax
377 @@ -765,10 +802,27 @@ __condvar_cleanup2:
378 movl $SYS_futex, %eax
379 syscall
380
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
384 + cancellation. */
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
389 + cmpl $PI_BIT, %eax
390 + jne 7f
391 +
392 + movl (%rdi), %eax
393 + andl $TID_MASK, %eax
394 + cmpl %eax, %fs:TID
395 + jne 7f
396 + /* We managed to get the lock. Fix it up before returning. */
397 + callq __pthread_mutex_cond_lock_adjust
398 + jmp 8f
399 +
400 +7: callq __pthread_mutex_cond_lock
401
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
410 @@ -23,6 +23,7 @@
411 #include <lowlevelcond.h>
412 #include <tcb-offsets.h>
413 #include <pthread-pi-defines.h>
414 +#include <pthread-errnos.h>
415
416 #include <kernel-features.h>
417
418 @@ -137,12 +138,32 @@ __pthread_cond_wait:
419 movl $SYS_futex, %eax
420 syscall
421
422 - movl $1, %r8d
423 + cmpl $0, %eax
424 + sete %r8b
425 +
426 #ifdef __ASSUME_REQUEUE_PI
427 jmp 62f
428 #else
429 - cmpq $-4095, %rax
430 - jnae 62f
431 + je 62f
432 +
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.
443 +
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
450 + jne 62f
451
452 # ifndef __ASSUME_PRIVATE_FUTEX
453 movl $FUTEX_WAIT, %esi
454 @@ -155,7 +176,7 @@ __pthread_cond_wait:
455 #else
456 orl %fs:PRIVATE_FUTEX, %esi
457 #endif
458 -60: xorl %r8d, %r8d
459 +60: xorb %r8b, %r8b
460 movl $SYS_futex, %eax
461 syscall
462
463 @@ -185,10 +206,10 @@ __pthread_cond_wait:
464 jne 16f
465
466 cmpq 24(%rsp), %r9
467 - jbe 8b
468 + jbe 19f
469
470 cmpq %rax, %r9
471 - jna 8b
472 + jna 19f
473
474 incq woken_seq(%rdi)
475
476 @@ -230,7 +251,7 @@ __pthread_cond_wait:
477 /* If requeue_pi is used the kernel performs the locking of the
478 mutex. */
479 11: movq 16(%rsp), %rdi
480 - testl %r8d, %r8d
481 + testb %r8b, %r8b
482 jnz 18f
483
484 callq __pthread_mutex_cond_lock
485 @@ -247,6 +268,23 @@ __pthread_cond_wait:
486 xorl %eax, %eax
487 jmp 14b
488
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
492 + jz 8b
493 +
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
496 + correctly. */
497 + movq 16(%rsp), %rdi
498 + callq __pthread_mutex_cond_lock_adjust
499 + movq %rdi, %r8
500 + xorl %esi, %esi
501 + callq __pthread_mutex_unlock_usercnt
502 + /* Reload cond_var. */
503 + movq 8(%rsp), %rdi
504 + jmp 8b
505 +
506 /* Initial locking failed. */
507 1:
508 #if cond_lock != 0
509 @@ -324,6 +362,7 @@ __pthread_cond_wait:
510
511 13: movq %r10, %rax
512 jmp 14b
513 +
514 .size __pthread_cond_wait, .-__pthread_cond_wait
515 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
516 GLIBC_2_3_2)
517 @@ -454,10 +493,28 @@ __condvar_cleanup1:
518 movl $SYS_futex, %eax
519 syscall
520
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
524 + cancellation. */
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
529 + cmpl $PI_BIT, %eax
530 + jne 7f
531 +
532 + movl (%rdi), %eax
533 + andl $TID_MASK, %eax
534 + cmpl %eax, %fs:TID
535 + jne 7f
536 + /* We managed to get the lock. Fix it up before returning. */
537 + callq __pthread_mutex_cond_lock_adjust
538 + jmp 8f
539 +
540
541 - movq 24(%rsp), %rdi
542 +7: callq __pthread_mutex_cond_lock
543 +
544 +8: movq 24(%rsp), %rdi
545 .LcallUR:
546 call _Unwind_Resume@PLT
547 hlt
548 @@ -476,11 +533,11 @@ __condvar_cleanup1:
549 .uleb128 .LcleanupSTART-.LSTARTCODE
550 .uleb128 .LcleanupEND-.LcleanupSTART
551 .uleb128 __condvar_cleanup1-.LSTARTCODE
552 - .uleb128 0
553 + .uleb128 0
554 .uleb128 .LcallUR-.LSTARTCODE
555 .uleb128 .LENDCODE-.LcallUR
556 .uleb128 0
557 - .uleb128 0
558 + .uleb128 0
559 .Lcstend:
560
561
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
565 @@ -0,0 +1,249 @@
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.
569 +
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.
574 +
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.
579 +
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/>. */
583 +
584 +#include <pthread.h>
585 +#include <stdio.h>
586 +#include <stdlib.h>
587 +#include <string.h>
588 +#include <errno.h>
589 +#include <sys/types.h>
590 +#include <sys/syscall.h>
591 +#include <unistd.h>
592 +#include <sys/time.h>
593 +#include <time.h>
594 +
595 +#define THREADS_NUM 5
596 +#define MAXITER 50000
597 +
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;
603 +
604 +typedef void * (*threadfunc) (void *);
605 +
606 +void *
607 +thread_fun_timed (void *arg)
608 +{
609 + int *ret = arg;
610 + int rv, i;
611 +
612 + printf ("Started thread_fun_timed[%d]\n", *ret);
613 +
614 + for (i = 0; i < MAXITER / THREADS_NUM; i++)
615 + {
616 + rv = pthread_mutex_lock (&mutex);
617 + if (rv)
618 + {
619 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
620 + *ret = 1;
621 + goto out;
622 + }
623 +
624 + while (!pending)
625 + {
626 + struct timespec ts;
627 + clock_gettime(CLOCK_REALTIME, &ts);
628 + ts.tv_sec += 20;
629 + rv = pthread_cond_timedwait (&cond, &mutex, &ts);
630 +
631 + /* There should be no timeout either. */
632 + if (rv)
633 + {
634 + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
635 + *ret = 1;
636 + goto out;
637 + }
638 + }
639 +
640 + pending--;
641 +
642 + rv = pthread_mutex_unlock (&mutex);
643 + if (rv)
644 + {
645 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
646 + *ret = 1;
647 + goto out;
648 + }
649 + }
650 +
651 + *ret = 0;
652 +
653 +out:
654 + return ret;
655 +}
656 +
657 +void *
658 +thread_fun (void *arg)
659 +{
660 + int *ret = arg;
661 + int rv, i;
662 +
663 + printf ("Started thread_fun[%d]\n", *ret);
664 +
665 + for (i = 0; i < MAXITER / THREADS_NUM; i++)
666 + {
667 + rv = pthread_mutex_lock (&mutex);
668 + if (rv)
669 + {
670 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
671 + *ret = 1;
672 + goto out;
673 + }
674 +
675 + while (!pending)
676 + {
677 + rv = pthread_cond_wait (&cond, &mutex);
678 +
679 + if (rv)
680 + {
681 + printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
682 + *ret = 1;
683 + goto out;
684 + }
685 + }
686 +
687 + pending--;
688 +
689 + rv = pthread_mutex_unlock (&mutex);
690 + if (rv)
691 + {
692 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
693 + *ret = 1;
694 + goto out;
695 + }
696 + }
697 +
698 + *ret = 0;
699 +
700 +out:
701 + return ret;
702 +}
703 +
704 +static int
705 +do_test_wait (threadfunc f)
706 +{
707 + int i;
708 + int rv;
709 + int counter = 0;
710 + int retval[THREADS_NUM];
711 +
712 + puts ("Starting test");
713 +
714 + rv = pthread_mutexattr_init (&mutex_attr);
715 + if (rv)
716 + {
717 + printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv);
718 + return 1;
719 + }
720 +
721 + rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT);
722 + if (rv)
723 + {
724 + printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv);
725 + return 1;
726 + }
727 +
728 + rv = pthread_mutex_init (&mutex, &mutex_attr);
729 + if (rv)
730 + {
731 + printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv);
732 + return 1;
733 + }
734 +
735 + rv = pthread_cond_init (&cond, NULL);
736 + if (rv)
737 + {
738 + printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv);
739 + return 1;
740 + }
741 +
742 + for (i = 0; i < THREADS_NUM; i++)
743 + {
744 + retval[i] = i;
745 + rv = pthread_create (&threads[i], NULL, f, &retval[i]);
746 + if (rv)
747 + {
748 + printf ("pthread_create: %s(%d)\n", strerror (rv), rv);
749 + return 1;
750 + }
751 + }
752 +
753 + for (; counter < MAXITER; counter++)
754 + {
755 + rv = pthread_mutex_lock (&mutex);
756 + if (rv)
757 + {
758 + printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
759 + return 1;
760 + }
761 +
762 + if (!(counter % 100))
763 + printf ("counter: %d\n", counter);
764 + pending += 1;
765 +
766 + rv = pthread_cond_signal (&cond);
767 + if (rv)
768 + {
769 + printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv);
770 + return 1;
771 + }
772 +
773 + rv = pthread_mutex_unlock (&mutex);
774 + if (rv)
775 + {
776 + printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
777 + return 1;
778 + }
779 + }
780 +
781 + for (i = 0; i < THREADS_NUM; i++)
782 + {
783 + void *ret;
784 + rv = pthread_join (threads[i], &ret);
785 + if (rv)
786 + {
787 + printf ("pthread_join: %s(%d)\n", strerror (rv), rv);
788 + return 1;
789 + }
790 + if (ret && *(int *)ret)
791 + {
792 + printf ("Thread %d returned with an error\n", i);
793 + return 1;
794 + }
795 + }
796 +
797 + return 0;
798 +}
799 +
800 +static int
801 +do_test (void)
802 +{
803 + puts ("Testing pthread_cond_wait");
804 + int ret = do_test_wait (thread_fun);
805 + if (ret)
806 + return ret;
807 +
808 + puts ("Testing pthread_cond_timedwait");
809 + return do_test_wait (thread_fun_timed);
810 +}
811 +
812 +#define TIMEOUT 20
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
818 @@ -0,0 +1,281 @@
819 +/* Verify that condition variables synchronized by PI mutexes don't hang on
820 + on cancellation.
821 + Copyright (C) 2012-2013 Free Software Foundation, Inc.
822 + This file is part of the GNU C Library.
823 +
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.
828 +
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.
833 +
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/>. */
837 +
838 +#include <pthread.h>
839 +#include <stdio.h>
840 +#include <stdlib.h>
841 +#include <stdint.h>
842 +#include <string.h>
843 +#include <errno.h>
844 +#include <sys/types.h>
845 +#include <sys/syscall.h>
846 +#include <unistd.h>
847 +#include <sys/time.h>
848 +#include <time.h>
849 +
850 +#define NUM 5
851 +#define ITERS 10000
852 +#define COUNT 100
853 +
854 +typedef void *(*thr_func) (void *);
855 +
856 +pthread_mutex_t mutex;
857 +pthread_cond_t cond;
858 +
859 +void cleanup (void *u)
860 +{
861 + /* pthread_cond_wait should always return with the mutex locked. */
862 + if (pthread_mutex_unlock (&mutex))
863 + abort ();
864 +}
865 +
866 +void *
867 +signaller (void *u)
868 +{
869 + int i, ret = 0;
870 + void *tret = NULL;
871 +
872 + for (i = 0; i < ITERS; i++)
873 + {
874 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
875 + {
876 + tret = (void *)1;
877 + printf ("signaller:mutex_lock failed: %s\n", strerror (ret));
878 + goto out;
879 + }
880 + if ((ret = pthread_cond_signal (&cond)) != 0)
881 + {
882 + tret = (void *)1;
883 + printf ("signaller:signal failed: %s\n", strerror (ret));
884 + goto unlock_out;
885 + }
886 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
887 + {
888 + tret = (void *)1;
889 + printf ("signaller:mutex_unlock failed: %s\n", strerror (ret));
890 + goto out;
891 + }
892 + pthread_testcancel ();
893 + }
894 +
895 +out:
896 + return tret;
897 +
898 +unlock_out:
899 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
900 + printf ("signaller:mutex_unlock[2] failed: %s\n", strerror (ret));
901 + goto out;
902 +}
903 +
904 +void *
905 +waiter (void *u)
906 +{
907 + int i, ret = 0;
908 + void *tret = NULL;
909 + int seq = (uintptr_t) u;
910 +
911 + for (i = 0; i < ITERS / NUM; i++)
912 + {
913 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
914 + {
915 + tret = (void *) (uintptr_t) 1;
916 + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
917 + goto out;
918 + }
919 + pthread_cleanup_push (cleanup, NULL);
920 +
921 + if ((ret = pthread_cond_wait (&cond, &mutex)) != 0)
922 + {
923 + tret = (void *) (uintptr_t) 1;
924 + printf ("waiter[%u]:wait failed: %s\n", seq, strerror (ret));
925 + goto unlock_out;
926 + }
927 +
928 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
929 + {
930 + tret = (void *) (uintptr_t) 1;
931 + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
932 + goto out;
933 + }
934 + pthread_cleanup_pop (0);
935 + }
936 +
937 +out:
938 + puts ("waiter tests done");
939 + return tret;
940 +
941 +unlock_out:
942 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
943 + printf ("waiter:mutex_unlock[2] failed: %s\n", strerror (ret));
944 + goto out;
945 +}
946 +
947 +void *
948 +timed_waiter (void *u)
949 +{
950 + int i, ret;
951 + void *tret = NULL;
952 + int seq = (uintptr_t) u;
953 +
954 + for (i = 0; i < ITERS / NUM; i++)
955 + {
956 + struct timespec ts;
957 +
958 + if ((ret = clock_gettime(CLOCK_REALTIME, &ts)) != 0)
959 + {
960 + tret = (void *) (uintptr_t) 1;
961 + printf ("%u:clock_gettime failed: %s\n", seq, strerror (errno));
962 + goto out;
963 + }
964 + ts.tv_sec += 20;
965 +
966 + if ((ret = pthread_mutex_lock (&mutex)) != 0)
967 + {
968 + tret = (void *) (uintptr_t) 1;
969 + printf ("waiter[%u]:mutex_lock failed: %s\n", seq, strerror (ret));
970 + goto out;
971 + }
972 + pthread_cleanup_push (cleanup, NULL);
973 +
974 + /* We should not time out either. */
975 + if ((ret = pthread_cond_timedwait (&cond, &mutex, &ts)) != 0)
976 + {
977 + tret = (void *) (uintptr_t) 1;
978 + printf ("waiter[%u]:timedwait failed: %s\n", seq, strerror (ret));
979 + goto unlock_out;
980 + }
981 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
982 + {
983 + tret = (void *) (uintptr_t) 1;
984 + printf ("waiter[%u]:mutex_unlock failed: %s\n", seq, strerror (ret));
985 + goto out;
986 + }
987 + pthread_cleanup_pop (0);
988 + }
989 +
990 +out:
991 + puts ("timed_waiter tests done");
992 + return tret;
993 +
994 +unlock_out:
995 + if ((ret = pthread_mutex_unlock (&mutex)) != 0)
996 + printf ("waiter[%u]:mutex_unlock[2] failed: %s\n", seq, strerror (ret));
997 + goto out;
998 +}
999 +
1000 +int
1001 +do_test_wait (thr_func f)
1002 +{
1003 + pthread_t w[NUM];
1004 + pthread_t s;
1005 + pthread_mutexattr_t attr;
1006 + int i, j, ret = 0;
1007 + void *thr_ret;
1008 +
1009 + for (i = 0; i < COUNT; i++)
1010 + {
1011 + if ((ret = pthread_mutexattr_init (&attr)) != 0)
1012 + {
1013 + printf ("mutexattr_init failed: %s\n", strerror (ret));
1014 + goto out;
1015 + }
1016 +
1017 + if ((ret = pthread_mutexattr_setprotocol (&attr,
1018 + PTHREAD_PRIO_INHERIT)) != 0)
1019 + {
1020 + printf ("mutexattr_setprotocol failed: %s\n", strerror (ret));
1021 + goto out;
1022 + }
1023 +
1024 + if ((ret = pthread_cond_init (&cond, NULL)) != 0)
1025 + {
1026 + printf ("cond_init failed: %s\n", strerror (ret));
1027 + goto out;
1028 + }
1029 +
1030 + if ((ret = pthread_mutex_init (&mutex, &attr)) != 0)
1031 + {
1032 + printf ("mutex_init failed: %s\n", strerror (ret));
1033 + goto out;
1034 + }
1035 +
1036 + for (j = 0; j < NUM; j++)
1037 + if ((ret = pthread_create (&w[j], NULL,
1038 + f, (void *) (uintptr_t) j)) != 0)
1039 + {
1040 + printf ("waiter[%d]: create failed: %s\n", j, strerror (ret));
1041 + goto out;
1042 + }
1043 +
1044 + if ((ret = pthread_create (&s, NULL, signaller, NULL)) != 0)
1045 + {
1046 + printf ("signaller: create failed: %s\n", strerror (ret));
1047 + goto out;
1048 + }
1049 +
1050 + for (j = 0; j < NUM; j++)
1051 + {
1052 + pthread_cancel (w[j]);
1053 +
1054 + if ((ret = pthread_join (w[j], &thr_ret)) != 0)
1055 + {
1056 + printf ("waiter[%d]: join failed: %s\n", j, strerror (ret));
1057 + goto out;
1058 + }
1059 +
1060 + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
1061 + {
1062 + ret = 1;
1063 + goto out;
1064 + }
1065 + }
1066 +
1067 + /* The signalling thread could have ended before it was cancelled. */
1068 + pthread_cancel (s);
1069 +
1070 + if ((ret = pthread_join (s, &thr_ret)) != 0)
1071 + {
1072 + printf ("signaller: join failed: %s\n", strerror (ret));
1073 + goto out;
1074 + }
1075 +
1076 + if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
1077 + {
1078 + ret = 1;
1079 + goto out;
1080 + }
1081 + }
1082 +
1083 +out:
1084 + return ret;
1085 +}
1086 +
1087 +int
1088 +do_test (int argc, char **argv)
1089 +{
1090 + int ret = do_test_wait (waiter);
1091 +
1092 + if (ret)
1093 + return ret;
1094 +
1095 + return do_test_wait (timed_waiter);
1096 +}
1097 +
1098 +#define TIMEOUT 5
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
1103 @@ -0,0 +1,110 @@
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.
1107 +
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.
1112 +
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.
1117 +
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/>. */
1121 +
1122 +#include <pthread.h>
1123 +#include <stdio.h>
1124 +#include <stdint.h>
1125 +#include <string.h>
1126 +#include <unistd.h>
1127 +
1128 +pthread_mutex_t mutex;
1129 +pthread_cond_t cond;
1130 +
1131 +#define CHECK_RETURN_VAL_OR_FAIL(ret,str) \
1132 + ({ if ((ret) != 0) \
1133 + { \
1134 + printf ("%s failed: %s\n", (str), strerror (ret)); \
1135 + ret = 1; \
1136 + goto out; \
1137 + } \
1138 + })
1139 +
1140 +
1141 +void
1142 +clean (void *arg)
1143 +{
1144 + puts ("clean: Unlocking mutex...");
1145 + pthread_mutex_unlock ((pthread_mutex_t *) arg);
1146 + puts ("clean: Mutex unlocked...");
1147 +}
1148 +
1149 +void *
1150 +thr (void *arg)
1151 +{
1152 + int ret = 0;
1153 + pthread_mutexattr_t mutexAttr;
1154 + ret = pthread_mutexattr_init (&mutexAttr);
1155 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_init");
1156 +
1157 + ret = pthread_mutexattr_setprotocol (&mutexAttr, PTHREAD_PRIO_INHERIT);
1158 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutexattr_setprotocol");
1159 +
1160 + ret = pthread_mutex_init (&mutex, &mutexAttr);
1161 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_init");
1162 +
1163 + ret = pthread_cond_init (&cond, 0);
1164 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_init");
1165 +
1166 + puts ("th: Init done, entering wait...");
1167 +
1168 + pthread_cleanup_push (clean, (void *) &mutex);
1169 + ret = pthread_mutex_lock (&mutex);
1170 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_mutex_lock");
1171 + while (1)
1172 + {
1173 + ret = pthread_cond_wait (&cond, &mutex);
1174 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cond_wait");
1175 + }
1176 + pthread_cleanup_pop (1);
1177 +
1178 +out:
1179 + return (void *) (uintptr_t) ret;
1180 +}
1181 +
1182 +int
1183 +do_test (void)
1184 +{
1185 + pthread_t thread;
1186 + int ret = 0;
1187 + void *thr_ret = 0;
1188 + ret = pthread_create (&thread, 0, thr, &thr_ret);
1189 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_create");
1190 +
1191 + puts ("main: Thread created, waiting a bit...");
1192 + sleep (2);
1193 +
1194 + puts ("main: Cancelling thread...");
1195 + ret = pthread_cancel (thread);
1196 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_cancel");
1197 +
1198 + puts ("main: Joining th...");
1199 + ret = pthread_join (thread, NULL);
1200 + CHECK_RETURN_VAL_OR_FAIL (ret, "pthread_join");
1201 +
1202 + if (thr_ret != NULL)
1203 + return 1;
1204 +
1205 + puts ("main: Joined thread, done!");
1206 +
1207 +out:
1208 + return ret;
1209 +}
1210 +
1211 +#define TEST_FUNCTION do_test ()
1212 +#define TIMEOUT 5
1213 +#include "../test-skeleton.c"