aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-06-24 02:50:16 +0000
committerUlrich Drepper <drepper@redhat.com>2003-06-24 02:50:16 +0000
commit67b78ef91b1441c7f94fe03e1bad161d5912f5ac (patch)
treeae9686b619a6a88901b6ecae921be3a8d1b48e47
parent7b0a32a30505e02f2b138b1695096b0ddb2ab62d (diff)
downloadglibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.tar
glibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.tar.gz
glibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.tar.bz2
glibc-67b78ef91b1441c7f94fe03e1bad161d5912f5ac.zip
Update.
* sysdeps/pthread/aio_misc.h: Mark __aio_requests_mutex, __aio_enqueue_request, __aio_find_req, __aio_find_req_fd, __aio_free_request, __aio_notify, and __aio_sigqueue as hidden. * sysdeps/pthread/aio_suspend.c (aio_suspend): Set errno to the result of pthread_cond_wait if there was an error. Use pthread_cleanup_* instead of __lbic_cleanup_region_*.
-rw-r--r--ChangeLog9
-rw-r--r--nptl/ChangeLog13
-rw-r--r--nptl/pthreadP.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S216
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S232
-rw-r--r--nptl/tst-cancel17.c147
-rw-r--r--nptl/tst-cond8.c2
-rw-r--r--sysdeps/pthread/aio_misc.h23
-rw-r--r--sysdeps/pthread/aio_suspend.c8
9 files changed, 475 insertions, 177 deletions
diff --git a/ChangeLog b/ChangeLog
index 69dce621b7..571330c35d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,12 @@
2003-06-23 Ulrich Drepper <drepper@redhat.com>
- * sysdeps/pthread/aio_suspend.c (aio_suspend): Set errno to EINTR
- if this is what pthread_cond_wait returned.
+ * sysdeps/pthread/aio_misc.h: Mark __aio_requests_mutex,
+ __aio_enqueue_request, __aio_find_req, __aio_find_req_fd,
+ __aio_free_request, __aio_notify, and __aio_sigqueue as hidden.
+
+ * sysdeps/pthread/aio_suspend.c (aio_suspend): Set errno to the result
+ of pthread_cond_wait if there was an error. Use pthread_cleanup_*
+ instead of __lbic_cleanup_region_*.
2003-06-20 Richard Henderson <rth@redhat.com>
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9a8f0a3800..c53fc8adf6 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,16 @@
+2003-06-23 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Rewrite
+ to use exception-based cleanup handler.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Likewise.
+
+ * tst-cond8.c (ch): Announce that we are done.
+
+ * pthreadP.h (__pthread_mutex_cond_lock): Mark with internal_function.
+
+ * tst-cancel17.c (tf): Retry aio_suspend in case of EINTR.
+ Also test aio_suspend with timeout value.
+
2003-06-22 Ulrich Drepper <drepper@redhat.com>
* pthreadP.h: Mark __pthread_mutex_unlock_usercnt also hidden.
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 64d0657659..b67e0ddb65 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -254,7 +254,7 @@ extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
attribute_hidden;
extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
- attribute_hidden;
+ attribute_hidden internal_function;
extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
attribute_hidden;
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 2f598980e5..d7ce84ebe4 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -81,32 +81,14 @@ __pthread_cond_timedwait:
addl $1, total_seq(%ebx)
adcl $0, total_seq+4(%ebx)
- /* Install cancellation handler. */
-#ifdef PIC
- call __i686.get_pc_thunk.cx
- addl $_GLOBAL_OFFSET_TABLE_, %ecx
- leal __condvar_cleanup@GOTOFF(%ecx), %eax
-#else
- leal __condvar_cleanup, %eax
-#endif
- subl $44, %esp
+ subl $20, %esp
.Lsubl:
- leal 28(%esp), %edx
- movl %esp, 8(%esp)
- movl %eax, 4(%esp)
- movl %edx, (%esp)
- call __pthread_cleanup_push
-
- /* Address of the mutex. */
- movl 68(%esp), %ecx
+
/* Get and store current wakeup_seq value. */
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
- movl %edi, 20(%esp)
- movl %edx, 24(%esp)
- /* Prepare structure passed to cancellation handler. */
- movl %ecx, (%esp)
- movl %ebx, 4(%esp)
+ movl %edi, 12(%esp)
+ movl %edx, 16(%esp)
/* Unlock. */
8: LOCK
@@ -117,18 +99,20 @@ __pthread_cond_timedwait:
#endif
jne 3f
+.LcleanupSTART:
4: call __pthread_enable_asynccancel
- movl %eax, 8(%esp)
+ movl %eax, (%esp)
/* Get the current time. */
movl %ebx, %edx
+.LebxmovedUR:
#ifdef __NR_clock_gettime
/* Get the clock number. Note that the field in the condvar
structure stores the number minus 1. */
movl cond_clock(%ebx), %ebx
/* Only clocks 0 and 1 are allowed. Both are handled in the
kernel. */
- leal 12(%esp), %ecx
+ leal 4(%esp), %ecx
movl $__NR_clock_gettime, %eax
ENTER_KERNEL
# ifndef __ASSUME_POSIX_TIMERS
@@ -136,27 +120,29 @@ __pthread_cond_timedwait:
je 19f
# endif
movl %edx, %ebx
+.LebxbackUR:
/* Compute relative timeout. */
movl (%ebp), %ecx
movl 4(%ebp), %edx
- subl 12(%esp), %ecx
- subl 16(%esp), %edx
+ subl 4(%esp), %ecx
+ subl 8(%esp), %edx
#else
/* Get the current time. */
- leal 12(%esp), %ebx
+ leal 4(%esp), %ebx
xorl %ecx, %ecx
movl $SYS_gettimeofday, %eax
ENTER_KERNEL
movl %edx, %ebx
+.LebxbackUR:
/* Compute relative timeout. */
- movl 16(%esp), %eax
+ movl 8(%esp), %eax
movl $1000, %edx
mul %edx /* Milli seconds to nano seconds. */
movl (%ebp), %ecx
movl 4(%ebp), %edx
- subl 12(%esp), %ecx
+ subl 4(%esp), %ecx
subl %eax, %edx
#endif
jns 12f
@@ -166,19 +152,22 @@ __pthread_cond_timedwait:
js 13f
/* Store relative timeout. */
-21: movl %ecx, 12(%esp)
- movl %edx, 16(%esp)
- leal 12(%esp), %esi
+21: movl %ecx, 4(%esp)
+ movl %edx, 8(%esp)
+ leal 4(%esp), %esi
xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
movl %edi, %edx
addl $wakeup_seq, %ebx
+.Ladd_wakeup:
movl $SYS_futex, %eax
ENTER_KERNEL
subl $wakeup_seq, %ebx
+.Lsub_wakeup:
movl %eax, %esi
- movl 8(%esp), %eax
+ movl (%esp), %eax
call __pthread_disable_asynccancel
+.LcleanupEND:
/* Lock. */
movl $1, %eax
@@ -197,10 +186,10 @@ __pthread_cond_timedwait:
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
- cmpl 24(%esp), %edx
+ cmpl 16(%esp), %edx
ja 7f
jb 15f
- cmpl 20(%esp), %edi
+ cmpl 12(%esp), %edi
jbe 15f
7: cmpl %ecx, %edx
@@ -230,12 +219,9 @@ __pthread_cond_timedwait:
jne 10f
/* Remove cancellation handler. */
-11: movl 28+CLEANUP_PREV(%esp), %edx
- movl %edx, %gs:CLEANUP
-
- /* Trick ahead: (%esp) contains the address of the mutex. */
+11: movl 44(%esp), %eax
call __pthread_mutex_cond_lock
- addl $44, %esp
+ addl $20, %esp
.Laddl:
/* We return the result of the mutex_lock operation if it failed. */
@@ -320,19 +306,19 @@ __pthread_cond_timedwait:
#if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
/* clock_gettime not available. */
.LSbl4:
-19: leal 12(%esp), %ebx
+19: leal 4(%esp), %ebx
xorl %ecx, %ecx
movl $SYS_gettimeofday, %eax
ENTER_KERNEL
movl %edx, %ebx
/* Compute relative timeout. */
- movl 16(%esp), %eax
+ movl 8(%esp), %eax
movl $1000, %edx
mul %edx /* Milli seconds to nano seconds. */
movl (%ebp), %ecx
movl 4(%ebp), %edx
- subl 12(%esp), %ecx
+ subl 4(%esp), %ecx
subl %eax, %edx
jns 20f
addl $1000000000, %edx
@@ -341,12 +327,112 @@ __pthread_cond_timedwait:
js 13b
jmp 21b
#endif
-.LENDCODE:
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)
+ .type __condvar_cleanup3, @function
+__condvar_cleanup3:
+ leal wakeup_seq(%edx), %ebx # XXX Is this correct? %edx preserved?
+.LSbl5:
+ .size __condvar_cleanup3, .-__condvar_cleanup3
+ .type __condvar_cleanup2, @function
+__condvar_cleanup2:
+ subl $wakeup_seq, %ebx
+ .size __condvar_cleanup2, .-__condvar_cleanup2
+ .type __condvar_cleanup, @function
+__condvar_cleanup:
+ movl %eax, %esi
+
+ /* Get internal lock. */
+ movl $1, %eax
+ LOCK
+#if cond_lock == 0
+ xaddl %eax, (%ebx)
+#else
+ xaddl %eax, cond_lock(%ebx)
+#endif
+ testl %eax, %eax
+ je 1f
+
+#if cond_lock == 0
+ movl %ebx, %ecx
+#else
+ leal cond_lock(%ebx), %ecx
+#endif
+ call __lll_mutex_lock_wait
+
+1: addl $1, wakeup_seq(%ebx)
+ adcl $0, wakeup_seq+4(%ebx)
+
+ addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+ LOCK
+ subl $1, cond_lock(%ebx)
+ je 2f
+
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+ call __lll_mutex_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: addl $wakeup_seq, %ebx
+ movl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %edx
+ ENTER_KERNEL
+
+ movl 44(%esp), %eax
+ call __pthread_mutex_cond_lock
+
+ movl %esi, (%esp)
+.LcallUR:
+ call _Unwind_Resume
+ hlt
+.LENDCODE:
+ .size __condvar_cleanup, .-__condvar_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x0b # call-site format
+ # DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .long .LcleanupSTART-.LSTARTCODE
+ .long .Ladd_wakeup-.LcleanupSTART
+ .long __condvar_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .LebxmovedUR-.LSTARTCODE
+ .long .LebxbackUR-.LebxmovedUR
+ .long __condvar_cleanup3-.LSTARTCODE
+ .uleb128 0
+ .long .LebxmovedUR-.LSTARTCODE
+ .long .Ladd_wakeup-.LebxmovedUR
+ .long __condvar_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_wakeup-.LSTARTCODE
+ .long .Lsub_wakeup-.Ladd_wakeup
+ .long __condvar_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_wakeup-.LSTARTCODE
+ .long .LcleanupEND-.Lsub_wakeup
+ .long __condvar_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .LcallUR-.LSTARTCODE
+ .long .LENDCODE-.LcallUR
+ .long 0
+ .uleb128 0
+.Lcstend:
+
+
.section .eh_frame,"a",@progbits
.LSTARTFRAME:
.long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
@@ -354,10 +440,10 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.long 0 # CIE ID.
.byte 1 # Version number.
#ifdef SHARED
- .string "zR" # NUL-terminated augmentation
+ .string "zPLR" # NUL-terminated augmentation
# string.
#else
- .ascii "\0" # NUL-terminated augmentation
+ .string "zPL" # NUL-terminated augmentation
# string.
#endif
.uleb128 1 # Code alignment factor.
@@ -365,9 +451,20 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.byte 8 # Return address register
# column.
#ifdef SHARED
- .uleb128 1 # Augmentation value length.
- .byte 0x1b # Encoding: DW_EH_PE_pcrel
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
# + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
#endif
.byte 0x0c # DW_CFA_def_cfa
.uleb128 4
@@ -387,8 +484,11 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.long .LSTARTCODE # Start address of the code.
#endif
.long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
#ifdef SHARED
- .uleb128 0 # No augmentation data.
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
#endif
.byte 0x40+.Lpush_ebp-.LSTARTCODE # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
@@ -413,7 +513,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.byte 2 # DW_CFA_advance_loc1
.byte .Lsubl-.Lpush_ebx
.byte 14 # DW_CFA_def_cfa_offset
- .uleb128 64
+ .uleb128 40
.byte 3 # DW_CFA_advance_loc2
.2byte .Laddl-.Lsubl
.byte 14 # DW_CFA_def_cfa_offset
@@ -455,6 +555,22 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
.byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 64
+ .byte 0x40+.LSbl5-.LSbl4 # DW_CFA_advance_loc+N
+#else
+ .byte 0x40+.LSbl5-.LSbl3 # DW_CFA_advance_loc+N
#endif
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 40
.align 4
.LENDFDE:
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index c98899ab05..6cf30cf41b 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -35,64 +35,6 @@
.text
- .align 16
- .type __condvar_cleanup, @function
- .globl __condvar_cleanup
- .hidden __condvar_cleanup
-__condvar_cleanup:
- pushl %ebx
- pushl %esi
- movl 12(%esp), %esi
-
- /* Get internal lock. */
- movl 4(%esi), %ebx
- movl $1, %eax
- LOCK
-#if cond_lock == 0
- xaddl %eax, (%ebx)
-#else
- xaddl %eax, cond_lock(%ebx)
-#endif
- testl %eax, %eax
- je 1f
-
-#if cond_lock == 0
- movl %ebx, %ecx
-#else
- leal cond_lock(%ebx), %ecx
-#endif
- call __lll_mutex_lock_wait
-
-1: addl $wakeup_seq, %ebx
- addl $1, (%ebx)
- adcl $0, 4(%ebx)
-
- addl $1, woken_seq-wakeup_seq(%ebx)
- adcl $0, woken_seq-wakeup_seq+4(%ebx)
-
- LOCK
- subl $1, cond_lock-wakeup_seq(%ebx)
- je 2f
-
- leal cond_lock-wakeup_seq(%ebx), %eax
- call __lll_mutex_unlock_wake
-
- /* Wake up all waiters to make sure no signal gets lost. */
-2: movl $FUTEX_WAKE, %ecx
- movl $SYS_futex, %eax
- movl $0x7fffffff, %edx
- ENTER_KERNEL
-
- pushl (%esi)
- call __pthread_mutex_cond_lock
- popl %eax
-
- popl %esi
- popl %ebx
- ret
- .size __condvar_cleanup, .-__condvar_cleanup
-
-
/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
.globl __pthread_cond_wait
.type __pthread_cond_wait, @function
@@ -136,31 +78,14 @@ __pthread_cond_wait:
addl $1, total_seq(%ebx)
adcl $0, total_seq+4(%ebx)
- /* Install cancellation handler. */
-#ifdef PIC
- call __i686.get_pc_thunk.cx
- addl $_GLOBAL_OFFSET_TABLE_, %ecx
- leal __condvar_cleanup@GOTOFF(%ecx), %eax
-#else
- leal __condvar_cleanup, %eax
-#endif
- subl $36, %esp
+ subl $12, %esp
.Lsubl:
- leal 20(%esp), %edx
- movl %esp, 8(%esp)
- movl %eax, 4(%esp)
- movl %edx, (%esp)
- call __pthread_cleanup_push
/* Get and store current wakeup_seq value. */
- movl 56(%esp), %ecx
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
- movl %edi, 12(%esp)
- movl %edx, 16(%esp)
- /* Prepare structure passed to cancellation handler. */
- movl %ecx, (%esp)
- movl %ebx, 4(%esp)
+ movl %edi, 4(%esp)
+ movl %edx, 8(%esp)
/* Unlock. */
8: LOCK
@@ -171,18 +96,22 @@ __pthread_cond_wait:
#endif
jne 3f
+.LcleanupSTART:
4: call __pthread_enable_asynccancel
- movl %eax, 8(%esp)
+ movl %eax, (%esp)
movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */
movl %edi, %edx
addl $wakeup_seq, %ebx
+.Ladd_wakeup:
movl $SYS_futex, %eax
ENTER_KERNEL
subl $wakeup_seq, %ebx
+.Lsub_wakeup:
- movl 8(%esp), %eax
+ movl (%esp), %eax
call __pthread_disable_asynccancel
+.LcleanupEND:
/* Lock. */
movl $1, %eax
@@ -201,10 +130,10 @@ __pthread_cond_wait:
movl wakeup_seq(%ebx), %edi
movl wakeup_seq+4(%ebx), %edx
- cmpl 16(%esp), %edx
+ cmpl 8(%esp), %edx
ja 7f
jb 8b
- cmpl 12(%esp), %edi
+ cmpl 4(%esp), %edi
jbe 8b
7: cmpl %ecx, %edx
@@ -224,13 +153,9 @@ __pthread_cond_wait:
#endif
jne 10f
- /* Remove cancellation handler. */
-11: movl 20+CLEANUP_PREV(%esp), %edx
- movl %edx, %gs:CLEANUP
-
- /* Trick ahead: (%esp) contains the address of the mutex. */
+11: movl 32(%esp), %eax
call __pthread_mutex_cond_lock
- addl $36, %esp
+ addl $12, %esp
.Laddl:
14: popl %ebx
@@ -306,23 +231,110 @@ __pthread_cond_wait:
movl %esi, %eax
jmp 14b
-.LENDCODE:
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2)
+ .type __condvar_cleanup2, @function
+__condvar_cleanup2:
+ subl $wakeup_seq, %ebx
+ .size __condvar_cleanup2, .-__condvar_cleanup2
+.LSbl4:
+ .type __condvar_cleanup, @function
+__condvar_cleanup:
+ movl %eax, %esi
+
+ /* Get internal lock. */
+ movl $1, %eax
+ LOCK
+#if cond_lock == 0
+ xaddl %eax, (%ebx)
+#else
+ xaddl %eax, cond_lock(%ebx)
+#endif
+ testl %eax, %eax
+ je 1f
+
+#if cond_lock == 0
+ movl %ebx, %ecx
+#else
+ leal cond_lock(%ebx), %ecx
+#endif
+ call __lll_mutex_lock_wait
+
+1: addl $1, wakeup_seq(%ebx)
+ adcl $0, wakeup_seq+4(%ebx)
+
+ addl $1, woken_seq(%ebx)
+ adcl $0, woken_seq+4(%ebx)
+
+ LOCK
+ subl $1, cond_lock(%ebx)
+ je 2f
+
+#if cond_lock == 0
+ movl %ebx, %eax
+#else
+ leal cond_lock(%ebx), %eax
+#endif
+ call __lll_mutex_unlock_wake
+
+ /* Wake up all waiters to make sure no signal gets lost. */
+2: addl $wakeup_seq, %ebx
+ movl $FUTEX_WAKE, %ecx
+ movl $SYS_futex, %eax
+ movl $0x7fffffff, %edx
+ ENTER_KERNEL
+
+ movl 32(%esp), %eax
+ call __pthread_mutex_cond_lock
+
+ movl %esi, (%esp)
+.LcallUR:
+ call _Unwind_Resume
+ hlt
+.LENDCODE:
+ .size __condvar_cleanup, .-__condvar_cleanup
+
+
+ .section .gcc_except_table,"a",@progbits
+.LexceptSTART:
+ .byte 0xff # @LPStart format (omit)
+ .byte 0xff # @TType format (omit)
+ .byte 0x0b # call-site format
+ # DW_EH_PE_sdata4
+ .uleb128 .Lcstend-.Lcstbegin
+.Lcstbegin:
+ .long .LcleanupSTART-.LSTARTCODE
+ .long .Ladd_wakeup-.LcleanupSTART
+ .long __condvar_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .Ladd_wakeup-.LSTARTCODE
+ .long .Lsub_wakeup-.Ladd_wakeup
+ .long __condvar_cleanup2-.LSTARTCODE
+ .uleb128 0
+ .long .Lsub_wakeup-.LSTARTCODE
+ .long .LcleanupEND-.Lsub_wakeup
+ .long __condvar_cleanup-.LSTARTCODE
+ .uleb128 0
+ .long .LcallUR-.LSTARTCODE
+ .long .LENDCODE-.LcallUR
+ .long 0
+ .uleb128 0
+.Lcstend:
+
.section .eh_frame,"a",@progbits
.LSTARTFRAME:
- .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
+ .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
.LSTARTCIE:
.long 0 # CIE ID.
.byte 1 # Version number.
#ifdef SHARED
- .string "zR" # NUL-terminated augmentation
+ .string "zPLR" # NUL-terminated augmentation
# string.
#else
- .ascii "\0" # NUL-terminated augmentation
+ .string "zPL" # NUL-terminated augmentation
# string.
#endif
.uleb128 1 # Code alignment factor.
@@ -330,9 +342,20 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.byte 8 # Return address register
# column.
#ifdef SHARED
- .uleb128 1 # Augmentation value length.
- .byte 0x1b # Encoding: DW_EH_PE_pcrel
+ .uleb128 7 # Augmentation value length.
+ .byte 0x9b # Personality: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4
+ # + DW_EH_PE_indirect
+ .long DW.ref.__gcc_personality_v0-.
+ .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
# + DW_EH_PE_sdata4.
+ .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
+ # + DW_EH_PE_sdata4.
+#else
+ .uleb128 6 # Augmentation value length.
+ .byte 0x0 # Personality: absolute
+ .long __gcc_personality_v0
+ .byte 0x0 # LSDA Encoding: absolute
#endif
.byte 0x0c # DW_CFA_def_cfa
.uleb128 4
@@ -352,8 +375,11 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.long .LSTARTCODE # Start address of the code.
#endif
.long .LENDCODE-.LSTARTCODE # Length of the code.
+ .uleb128 4 # Augmentation size
#ifdef SHARED
- .uleb128 0 # No augmentation data.
+ .long .LexceptSTART-.
+#else
+ .long .LexceptSTART
#endif
.byte 0x40+.Lpush_edi-.LSTARTCODE # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
@@ -373,7 +399,7 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.byte 2 # DW_CFA_advance_loc1
.byte .Lsubl-.Lpush_ebx
.byte 14 # DW_CFA_def_cfa_offset
- .uleb128 52
+ .uleb128 36
.byte 2 # DW_CFA_advance_loc1
.byte .Laddl-.Lsubl
.byte 14 # DW_CFA_def_cfa_offset
@@ -405,6 +431,9 @@ versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
.byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20
+ .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N
+ .byte 14 # DW_CFA_def_cfa_offset
+ .uleb128 28
.align 4
.LENDFDE:
@@ -419,3 +448,14 @@ __i686.get_pc_thunk.cx:
ret
.size __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
#endif
+
+#ifdef SHARED
+ .hidden DW.ref.__gcc_personality_v0
+ .weak DW.ref.__gcc_personality_v0
+ .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
+ .align 4
+ .type DW.ref.__gcc_personality_v0, @object
+ .size DW.ref.__gcc_personality_v0, 4
+DW.ref.__gcc_personality_v0:
+ .long __gcc_personality_v0
+#endif
diff --git a/nptl/tst-cancel17.c b/nptl/tst-cancel17.c
index 65b8c73ef8..861ca5ea69 100644
--- a/nptl/tst-cancel17.c
+++ b/nptl/tst-cancel17.c
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <aio.h>
+#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
@@ -44,19 +45,44 @@ tf (void *arg)
int r = pthread_barrier_wait (&b);
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
{
- puts ("barrier_wait failed");
+ puts ("tf: barrier_wait failed");
+ exit (1);
+ }
+
+ pthread_cleanup_push (cl, NULL);
+
+ const struct aiocb *l[1] = { arg };
+
+ TEMP_FAILURE_RETRY (aio_suspend (l, 1, NULL));
+
+ pthread_cleanup_pop (0);
+
+ puts ("tf: aio_suspend returned");
+
+ exit (1);
+}
+
+
+static void *
+tf2 (void *arg)
+{
+ int r = pthread_barrier_wait (&b);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ puts ("tf2: barrier_wait failed");
exit (1);
}
pthread_cleanup_push (cl, NULL);
const struct aiocb *l[1] = { arg };
+ struct timespec ts = { .tv_sec = 1000, .tv_nsec = 0 };
- aio_suspend (l, 1, NULL);
+ TEMP_FAILURE_RETRY (aio_suspend (l, 1, &ts));
pthread_cleanup_pop (0);
- puts ("aio_suspend returned");
+ puts ("tf2: aio_suspend returned");
exit (1);
}
@@ -108,7 +134,7 @@ do_test (void)
while (nanosleep (&ts, &ts) != 0)
continue;
- puts ("going to cancel in-time");
+ puts ("going to cancel tf in-time");
if (pthread_cancel (th) != 0)
{
puts ("1st cancel failed");
@@ -129,12 +155,61 @@ do_test (void)
if (cl_called == 0)
{
- puts ("cleanup handler not called");
+ puts ("tf cleanup handler not called");
return 1;
}
if (cl_called > 1)
{
- puts ("cleanup handler called more than once");
+ puts ("tf cleanup handler called more than once");
+ return 1;
+ }
+
+ cl_called = 0;
+
+ if (pthread_create (&th, NULL, tf2, &a) != 0)
+ {
+ puts ("2nd create failed");
+ return 1;
+ }
+
+ r = pthread_barrier_wait (&b);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ puts ("2nd barrier_wait failed");
+ exit (1);
+ }
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000;
+ while (nanosleep (&ts, &ts) != 0)
+ continue;
+
+ puts ("going to cancel tf2 in-time");
+ if (pthread_cancel (th) != 0)
+ {
+ puts ("2nd cancel failed");
+ return 1;
+ }
+
+ if (pthread_join (th, &status) != 0)
+ {
+ puts ("2nd join failed");
+ return 1;
+ }
+ if (status != PTHREAD_CANCELED)
+ {
+ puts ("2nd thread not canceled");
+ return 1;
+ }
+
+ if (cl_called == 0)
+ {
+ puts ("tf2 cleanup handler not called");
+ return 1;
+ }
+ if (cl_called > 1)
+ {
+ puts ("tf2 cleanup handler called more than once");
return 1;
}
@@ -156,43 +231,87 @@ do_test (void)
if (pthread_create (&th, NULL, tf, &a) != 0)
{
- puts ("2nd create failed");
+ puts ("3rd create failed");
return 1;
}
- puts ("going to cancel early");
+ puts ("going to cancel tf early");
if (pthread_cancel (th) != 0)
{
- puts ("2nd cancel failed");
+ puts ("3rd cancel failed");
return 1;
}
r = pthread_barrier_wait (&b);
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
{
- puts ("barrier_wait failed");
+ puts ("3rd barrier_wait failed");
exit (1);
}
if (pthread_join (th, &status) != 0)
{
- puts ("2nd join failed");
+ puts ("3rd join failed");
return 1;
}
if (status != PTHREAD_CANCELED)
{
- puts ("2nd thread not canceled");
+ puts ("3rd thread not canceled");
+ return 1;
+ }
+
+ if (cl_called == 0)
+ {
+ printf ("tf cleanup handler not called\n");
+ return 1;
+ }
+ if (cl_called > 1)
+ {
+ printf ("tf cleanup handler called more than once\n");
+ return 1;
+ }
+
+ cl_called = 0;
+
+ if (pthread_create (&th, NULL, tf2, &a) != 0)
+ {
+ puts ("4th create failed");
+ return 1;
+ }
+
+ puts ("going to cancel tf2 early");
+ if (pthread_cancel (th) != 0)
+ {
+ puts ("4th cancel failed");
+ return 1;
+ }
+
+ r = pthread_barrier_wait (&b);
+ if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ {
+ puts ("4th barrier_wait failed");
+ exit (1);
+ }
+
+ if (pthread_join (th, &status) != 0)
+ {
+ puts ("4th join failed");
+ return 1;
+ }
+ if (status != PTHREAD_CANCELED)
+ {
+ puts ("4th thread not canceled");
return 1;
}
if (cl_called == 0)
{
- printf ("cleanup handler not called\n");
+ printf ("tf2 cleanup handler not called\n");
return 1;
}
if (cl_called > 1)
{
- printf ("cleanup handler called more than once\n");
+ printf ("tf2 cleanup handler called more than once\n");
return 1;
}
diff --git a/nptl/tst-cond8.c b/nptl/tst-cond8.c
index 48451e7813..9c97a96fac 100644
--- a/nptl/tst-cond8.c
+++ b/nptl/tst-cond8.c
@@ -52,6 +52,8 @@ ch (void *arg)
puts ("ch: cannot unlock mutex");
exit (1);
}
+
+ puts ("ch done");
}
diff --git a/sysdeps/pthread/aio_misc.h b/sysdeps/pthread/aio_misc.h
index ee0df52970..05e60e7d1e 100644
--- a/sysdeps/pthread/aio_misc.h
+++ b/sysdeps/pthread/aio_misc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -90,38 +90,41 @@ struct requestlist
/* Lock for global I/O list of requests. */
-extern pthread_mutex_t __aio_requests_mutex;
+extern pthread_mutex_t __aio_requests_mutex attribute_hidden;
/* Enqueue request. */
extern struct requestlist *__aio_enqueue_request (aiocb_union *aiocbp,
int operation)
- internal_function;
+ attribute_hidden internal_function;
/* Find request entry for given AIO control block. */
extern struct requestlist *__aio_find_req (aiocb_union *elem)
- internal_function;
+ attribute_hidden internal_function;
/* Find request entry for given file descriptor. */
-extern struct requestlist *__aio_find_req_fd (int fildes) internal_function;
+extern struct requestlist *__aio_find_req_fd (int fildes)
+ attribute_hidden internal_function;
/* Remove request from the list. */
extern void __aio_remove_request (struct requestlist *last,
struct requestlist *req, int all)
- internal_function;
+ attribute_hidden internal_function;
/* Release the entry for the request. */
-extern void __aio_free_request (struct requestlist *req) internal_function;
+extern void __aio_free_request (struct requestlist *req)
+ attribute_hidden internal_function;
/* Notify initiator of request and tell this everybody listening. */
-extern void __aio_notify (struct requestlist *req) internal_function;
+extern void __aio_notify (struct requestlist *req)
+ attribute_hidden internal_function;
/* Notify initiator of request. */
extern int __aio_notify_only (struct sigevent *sigev, pid_t caller_pid)
- internal_function;
+ attribute_hidden internal_function;
/* Send the signal. */
extern int __aio_sigqueue (int sig, const union sigval val, pid_t caller_pid)
- internal_function;
+ attribute_hidden internal_function;
#endif /* aio_misc.h */
diff --git a/sysdeps/pthread/aio_suspend.c b/sysdeps/pthread/aio_suspend.c
index 92cac81036..8bc8f0e9a1 100644
--- a/sysdeps/pthread/aio_suspend.c
+++ b/sysdeps/pthread/aio_suspend.c
@@ -141,7 +141,7 @@ aio_suspend (list, nent, timeout)
.nent = nent
};
- __libc_cleanup_region_start (1, cleanup, &clparam);
+ pthread_cleanup_push (cleanup, &clparam);
if (timeout == NULL)
result = pthread_cond_wait (&cond, &__aio_requests_mutex);
@@ -165,7 +165,7 @@ aio_suspend (list, nent, timeout)
&abstime);
}
- __libc_cleanup_region_end (0);
+ pthread_cleanup_pop (0);
}
/* Now remove the entry in the waiting list for all requests
@@ -199,8 +199,8 @@ aio_suspend (list, nent, timeout)
form expected from `aio_suspend'. */
if (result == ETIMEDOUT)
__set_errno (EAGAIN);
- else if (result == EINTR)
- __set_errno (EINTR);
+ else
+ __set_errno (result);
result = -1;
}