* 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_*.
This commit is contained in:
Ulrich Drepper 2003-06-24 02:50:16 +00:00
parent 7b0a32a305
commit 67b78ef91b
9 changed files with 474 additions and 176 deletions

View File

@ -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>

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -18,6 +18,7 @@
02111-1307 USA. */
#include <aio.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
@ -44,7 +45,7 @@ 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);
}
@ -52,11 +53,36 @@ tf (void *arg)
const struct aiocb *l[1] = { arg };
aio_suspend (l, 1, NULL);
TEMP_FAILURE_RETRY (aio_suspend (l, 1, NULL));
pthread_cleanup_pop (0);
puts ("aio_suspend returned");
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 };
TEMP_FAILURE_RETRY (aio_suspend (l, 1, &ts));
pthread_cleanup_pop (0);
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 ("cleanup handler not called\n");
printf ("tf cleanup handler not called\n");
return 1;
}
if (cl_called > 1)
{
printf ("cleanup handler called more than once\n");
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 ("tf2 cleanup handler not called\n");
return 1;
}
if (cl_called > 1)
{
printf ("tf2 cleanup handler called more than once\n");
return 1;
}

View File

@ -52,6 +52,8 @@ ch (void *arg)
puts ("ch: cannot unlock mutex");
exit (1);
}
puts ("ch done");
}

View File

@ -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 */

View File

@ -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;
}