mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 00:10:10 +00:00
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_*.
This commit is contained in:
parent
7b0a32a305
commit
67b78ef91b
@ -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>
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,8 @@ ch (void *arg)
|
||||
puts ("ch: cannot unlock mutex");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
puts ("ch done");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user