diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S')
-rw-r--r-- | libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S | 243 |
1 files changed, 189 insertions, 54 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S index c3e6cbce6..b1c32ee4d 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -19,86 +19,98 @@ #include <sysdep.h> #include <pthread-errnos.h> -#include <tcb-offsets.h> -#include <tls.h> +#include <structsem.h> +#include <lowlevellock.h> -#ifndef UP -# define LOCK lock -#else -# define -#endif - -#define FUTEX_WAKE 1 +#if VALUE != 0 +# error "code needs to be rewritten for VALUE != 0" +#endif .text .globl __new_sem_wait .type __new_sem_wait,@function .align 16 - cfi_startproc __new_sem_wait: - /* First check for cancellation. */ - movl %gs:CANCELHANDLING, %eax - andl $0xfffffff9, %eax - cmpl $8, %eax - je 5f - +.LSTARTCODE: pushl %ebx - cfi_adjust_cfa_offset(4) +.Lpush_ebx: pushl %esi - cfi_adjust_cfa_offset(4) +.Lpush_esi: subl $4, %esp - cfi_adjust_cfa_offset(4) +.Lsub_esp: movl 16(%esp), %ebx - cfi_offset(3, -8) /* %ebx */ - cfi_offset(6, -12) /* %esi */ -3: movl (%ebx), %eax + movl (%ebx), %eax 2: testl %eax, %eax - je,pn 1f + je 1f leal -1(%eax), %edx LOCK cmpxchgl %edx, (%ebx) - jne,pn 2b - xorl %eax, %eax + jne 2b +7: xorl %eax, %eax - movl 4(%esp), %esi - cfi_restore(6) +9: movl 4(%esp), %esi movl 8(%esp), %ebx - cfi_restore(3) addl $12, %esp - cfi_adjust_cfa_offset(-12) +.Ladd_esp: ret - cfi_adjust_cfa_offset(8) - cfi_offset(3, -8) /* %ebx */ - cfi_offset(6, -12) /* %esi */ -1: call __pthread_enable_asynccancel +.Lafter_ret: +1: LOCK + incl NWAITERS(%ebx) + +.LcleanupSTART: +6: call __pthread_enable_asynccancel movl %eax, (%esp) +#if FUTEX_WAIT == 0 + movl PRIVATE(%ebx), %ecx +#else + movl $FUTEX_WAIT, %ecx + orl PRIVATE(%ebx), %ecx +#endif xorl %esi, %esi + xorl %edx, %edx movl $SYS_futex, %eax - movl %esi, %ecx - movl %esi, %edx ENTER_KERNEL movl %eax, %esi movl (%esp), %eax call __pthread_disable_asynccancel +.LcleanupEND: testl %esi, %esi - je 3b + je 3f cmpl $-EWOULDBLOCK, %esi - je 3b + jne 4f + +3: + movl (%ebx), %eax +5: testl %eax, %eax + je 6b + + leal -1(%eax), %edx + LOCK + cmpxchgl %edx, (%ebx) + jne 5b + + LOCK + decl NWAITERS(%ebx) + jmp 7b + +4: LOCK + decl NWAITERS(%ebx) + negl %esi #ifdef __PIC__ call __x86.get_pc_thunk.bx #else - movl $4f, %ebx -4: + movl $8f, %ebx +8: #endif addl $_GLOBAL_OFFSET_TABLE_, %ebx #if USE___THREAD @@ -115,20 +127,143 @@ __new_sem_wait: movl %esi, (%eax) #endif orl $-1, %eax - movl 4(%esp), %esi - cfi_restore(6) - movl 8(%esp), %ebx - cfi_restore(3) - addl $12, %esp - cfi_adjust_cfa_offset(-12) - ret -5: /* Canceled. */ - movl $0xffffffff, %gs:RESULT - LOCK - orl $0x10, %gs:CANCELHANDLING - movl %gs:CLEANUP_JMP_BUF, %eax - jmp HIDDEN_JUMPTARGET (__pthread_unwind) - cfi_endproc + jmp 9b .size __new_sem_wait,.-__new_sem_wait weak_alias(__new_sem_wait, sem_wait) + + + .type sem_wait_cleanup,@function +sem_wait_cleanup: + LOCK + decl NWAITERS(%ebx) + movl %eax, (%esp) +.LcallUR: + call _Unwind_Resume@PLT + hlt +.LENDCODE: + .size sem_wait_cleanup,.-sem_wait_cleanup + + + .section .gcc_except_table,"a",@progbits +.LexceptSTART: + .byte 0xff # @LPStart format (omit) + .byte 0xff # @TType format (omit) + .byte 0x01 # call-site format + # DW_EH_PE_uleb128 + .uleb128 .Lcstend-.Lcstbegin +.Lcstbegin: + .uleb128 .LcleanupSTART-.LSTARTCODE + .uleb128 .LcleanupEND-.LcleanupSTART + .uleb128 sem_wait_cleanup-.LSTARTCODE + .uleb128 0 + .uleb128 .LcallUR-.LSTARTCODE + .uleb128 .LENDCODE-.LcallUR + .uleb128 0 + .uleb128 0 +.Lcstend: + + + .section .eh_frame,"a",@progbits +.LSTARTFRAME: + .long .LENDCIE-.LSTARTCIE # Length of the CIE. +.LSTARTCIE: + .long 0 # CIE ID. + .byte 1 # Version number. +#ifdef SHARED + .string "zPLR" # NUL-terminated augmentation + # string. +#else + .string "zPL" # NUL-terminated augmentation + # string. +#endif + .uleb128 1 # Code alignment factor. + .sleb128 -4 # Data alignment factor. + .byte 8 # Return address register + # column. +#ifdef SHARED + .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 + .uleb128 4 + .byte 0x88 # DW_CFA_offset, column 0x10 + .uleb128 1 + .align 4 +.LENDCIE: + + .long .LENDFDE-.LSTARTFDE # Length of the FDE. +.LSTARTFDE: + .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. +#ifdef SHARED + .long .LSTARTCODE-. # PC-relative start address + # of the code. +#else + .long .LSTARTCODE # Start address of the code. +#endif + .long .LENDCODE-.LSTARTCODE # Length of the code. + .uleb128 4 # Augmentation size +#ifdef SHARED + .long .LexceptSTART-. +#else + .long .LexceptSTART +#endif + + .byte 4 # DW_CFA_advance_loc4 + .long .Lpush_ebx-.LSTARTCODE + .byte 14 # DW_CFA_def_cfa_offset + .uleb128 8 + .byte 0x83 # DW_CFA_offset %ebx + .uleb128 2 + .byte 4 # DW_CFA_advance_loc4 + .long .Lpush_esi-.Lpush_ebx + .byte 14 # DW_CFA_def_cfa_offset + .uleb128 12 + .byte 0x86 # DW_CFA_offset %esi + .uleb128 3 + .byte 4 # DW_CFA_advance_loc4 + .long .Lsub_esp-.Lpush_esi + .byte 14 # DW_CFA_def_cfa_offset + .uleb128 16 + .byte 4 # DW_CFA_advance_loc4 + .long .Ladd_esp-.Lsub_esp + .byte 14 # DW_CFA_def_cfa_offset + .uleb128 4 + .byte 0xc3 # DW_CFA_restore %ebx + .byte 0xc6 # DW_CFA_restore %esi + .byte 4 # DW_CFA_advance_loc4 + .long .Lafter_ret-.Ladd_esp + .byte 14 # DW_CFA_def_cfa_offset + .uleb128 16 + .byte 0x83 # DW_CFA_offset %ebx + .uleb128 2 + .byte 0x86 # DW_CFA_offset %esi + .uleb128 3 + .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 + |