1/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19#include <sysdep.h> 20#include <lowlevellock.h> 21#include <pthread-errnos.h> 22#include <structsem.h> 23 24 25 .text 26 27 .globl sem_wait 28 .type sem_wait,@function 29 .align 16 30sem_wait: 31.LSTARTCODE: 32 cfi_startproc 33 34#if VALUE == 0 35 movl (%rdi), %eax 36#else 37 movl VALUE(%rdi), %eax 38#endif 392: testl %eax, %eax 40 je 1f 41 42 leal -1(%rax), %edx 43 LOCK 44#if VALUE == 0 45 cmpxchgl %edx, (%rdi) 46#else 47 cmpxchgl %edx, VALUE(%rdi) 48#endif 49 jne 2b 50 51 xorl %eax, %eax 52 retq 53 54 /* This push is only needed to store the sem_t pointer for the 55 exception handler. */ 561: pushq %rdi 57 cfi_adjust_cfa_offset(8) 58 59 LOCK 60 addq $1, NWAITERS(%rdi) 61 62.LcleanupSTART: 636: call __pthread_enable_asynccancel 64 movl %eax, %r8d 65 66 xorq %r10, %r10 67 movl $SYS_futex, %eax 68#if FUTEX_WAIT == 0 69 movl PRIVATE(%rdi), %esi 70#else 71 movl $FUTEX_WAIT, %esi 72 orl PRIVATE(%rdi), %esi 73#endif 74 xorl %edx, %edx 75 syscall 76 movq %rax, %rcx 77 78 xchgq %r8, %rdi 79 call __pthread_disable_asynccancel 80.LcleanupEND: 81 movq %r8, %rdi 82 83 testq %rcx, %rcx 84 je 3f 85 cmpq $-EWOULDBLOCK, %rcx 86 jne 4f 87 883: 89#if VALUE == 0 90 movl (%rdi), %eax 91#else 92 movl VALUE(%rdi), %eax 93#endif 945: testl %eax, %eax 95 je 6b 96 97 leal -1(%rax), %edx 98 LOCK 99#if VALUE == 0 100 cmpxchgl %edx, (%rdi) 101#else 102 cmpxchgl %edx, VALUE(%rdi) 103#endif 104 jne 5b 105 106 xorl %eax, %eax 107 1089: LOCK 109 subq $1, NWAITERS(%rdi) 110 111 leaq 8(%rsp), %rsp 112 cfi_adjust_cfa_offset(-8) 113 114 retq 115 116 cfi_adjust_cfa_offset(8) 1174: negq %rcx 118#if USE___THREAD 119 movq errno@gottpoff(%rip), %rdx 120 movl %ecx, %fs:(%rdx) 121#else 122# error "not supported. %rcx and %rdi must be preserved" 123 callq __errno_location@plt 124 movl %ecx, (%rax) 125#endif 126 orl $-1, %eax 127 128 jmp 9b 129 .size sem_wait,.-sem_wait 130 131 132 .type sem_wait_cleanup,@function 133sem_wait_cleanup: 134 movq (%rsp), %rdi 135 LOCK 136 subq $1, NWAITERS(%rdi) 137 movq %rax, %rdi 138.LcallUR: 139 call _Unwind_Resume@PLT 140 hlt 141.LENDCODE: 142 cfi_endproc 143 .size sem_wait_cleanup,.-sem_wait_cleanup 144 145 146 .section .gcc_except_table,"a",@progbits 147.LexceptSTART: 148 .byte DW_EH_PE_omit # @LPStart format 149 .byte DW_EH_PE_omit # @TType format 150 .byte DW_EH_PE_uleb128 # call-site format 151 .uleb128 .Lcstend-.Lcstbegin 152.Lcstbegin: 153 .uleb128 .LcleanupSTART-.LSTARTCODE 154 .uleb128 .LcleanupEND-.LcleanupSTART 155 .uleb128 sem_wait_cleanup-.LSTARTCODE 156 .uleb128 0 157 .uleb128 .LcallUR-.LSTARTCODE 158 .uleb128 .LENDCODE-.LcallUR 159 .uleb128 0 160 .uleb128 0 161.Lcstend: 162 163 164#ifdef SHARED 165 .hidden DW.ref.__gcc_personality_v0 166 .weak DW.ref.__gcc_personality_v0 167 .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits 168 .align 8 169 .type DW.ref.__gcc_personality_v0, @object 170 .size DW.ref.__gcc_personality_v0, 8 171DW.ref.__gcc_personality_v0: 172 .quad __gcc_personality_v0 173#endif 174