diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | nptl/ChangeLog | 13 | ||||
-rw-r--r-- | nptl/pthreadP.h | 2 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S | 216 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S | 232 | ||||
-rw-r--r-- | nptl/tst-cancel17.c | 147 | ||||
-rw-r--r-- | nptl/tst-cond8.c | 2 | ||||
-rw-r--r-- | sysdeps/pthread/aio_misc.h | 23 | ||||
-rw-r--r-- | sysdeps/pthread/aio_suspend.c | 8 |
9 files changed, 475 insertions, 177 deletions
@@ -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; } |