]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-rh552960.patch
dhcpcd: fix delay after dhcp down.
[ipfire-2.x.git] / src / patches / glibc / glibc-rh552960.patch
CommitLineData
bb330e25
AF
1diff -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
23diff -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
138diff -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
270diff -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
278diff -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
407diff -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
562diff -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"
815diff -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"
1100diff -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"