chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / sem_wait.S
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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <sysdep.h>
21 #include <lowlevellock.h>
22 #include <shlib-compat.h>
23 #include <pthread-errnos.h>
24 #include <structsem.h>
25
26
27         .text
28
29         .globl  sem_wait
30         .type   sem_wait,@function
31         .align  16
32 sem_wait:
33 .LSTARTCODE:
34         cfi_startproc
35 #ifdef SHARED
36         cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect,
37                         DW.ref.__gcc_personality_v0)
38         cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART)
39 #else
40         cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0)
41         cfi_lsda(DW_EH_PE_udata4, .LexceptSTART)
42 #endif
43
44 #if VALUE == 0
45         movl    (%rdi), %eax
46 #else
47         movl    VALUE(%rdi), %eax
48 #endif
49 2:      testl   %eax, %eax
50         je      1f
51
52         leal    -1(%rax), %edx
53         LOCK
54 #if VALUE == 0
55         cmpxchgl %edx, (%rdi)
56 #else
57         cmpxchgl %edx, VALUE(%rdi)
58 #endif
59         jne     2b
60
61         xorl    %eax, %eax
62         retq
63
64         /* This push is only needed to store the sem_t pointer for the
65            exception handler.  */
66 1:      pushq   %rdi
67         cfi_adjust_cfa_offset(8)
68
69         LOCK
70         addq    $1, NWAITERS(%rdi)
71
72 .LcleanupSTART:
73 6:      call    __pthread_enable_asynccancel
74         movl    %eax, %r8d
75
76         xorq    %r10, %r10
77         movl    $SYS_futex, %eax
78 #if FUTEX_WAIT == 0
79         movl    PRIVATE(%rdi), %esi
80 #else
81         movl    $FUTEX_WAIT, %esi
82         orl     PRIVATE(%rdi), %esi
83 #endif
84         xorl    %edx, %edx
85         syscall
86         movq    %rax, %rcx
87
88         xchgq   %r8, %rdi
89         call    __pthread_disable_asynccancel
90 .LcleanupEND:
91         movq    %r8, %rdi
92
93         testq   %rcx, %rcx
94         je      3f
95         cmpq    $-EWOULDBLOCK, %rcx
96         jne     4f
97
98 3:
99 #if VALUE == 0
100         movl    (%rdi), %eax
101 #else
102         movl    VALUE(%rdi), %eax
103 #endif
104 5:      testl   %eax, %eax
105         je      6b
106
107         leal    -1(%rax), %edx
108         LOCK
109 #if VALUE == 0
110         cmpxchgl %edx, (%rdi)
111 #else
112         cmpxchgl %edx, VALUE(%rdi)
113 #endif
114         jne     5b
115
116         xorl    %eax, %eax
117
118 9:      LOCK
119         subq    $1, NWAITERS(%rdi)
120
121         leaq    8(%rsp), %rsp
122         cfi_adjust_cfa_offset(-8)
123
124         retq
125
126         cfi_adjust_cfa_offset(8)
127 4:      negq    %rcx
128 #if USE___THREAD
129         movq    errno@gottpoff(%rip), %rdx
130         movl    %ecx, %fs:(%rdx)
131 #else
132 # error "not supported.  %rcx and %rdi must be preserved"
133         callq   __errno_location@plt
134         movl    %ecx, (%rax)
135 #endif
136         orl     $-1, %eax
137
138         jmp 9b
139         .size   sem_wait,.-sem_wait
140
141
142         .type   sem_wait_cleanup,@function
143 sem_wait_cleanup:
144         movq    (%rsp), %rdi
145         LOCK
146         subq    $1, NWAITERS(%rdi)
147         movq    %rax, %rdi
148 .LcallUR:
149         call    _Unwind_Resume@PLT
150         hlt
151 .LENDCODE:
152         cfi_endproc
153         .size   sem_wait_cleanup,.-sem_wait_cleanup
154
155
156         .section .gcc_except_table,"a",@progbits
157 .LexceptSTART:
158         .byte   DW_EH_PE_omit                   # @LPStart format
159         .byte   DW_EH_PE_omit                   # @TType format
160         .byte   DW_EH_PE_uleb128                # call-site format
161         .uleb128 .Lcstend-.Lcstbegin
162 .Lcstbegin:
163         .uleb128 .LcleanupSTART-.LSTARTCODE
164         .uleb128 .LcleanupEND-.LcleanupSTART
165         .uleb128 sem_wait_cleanup-.LSTARTCODE
166         .uleb128  0
167         .uleb128 .LcallUR-.LSTARTCODE
168         .uleb128 .LENDCODE-.LcallUR
169         .uleb128 0
170         .uleb128  0
171 .Lcstend:
172
173
174 #ifdef SHARED
175         .hidden DW.ref.__gcc_personality_v0
176         .weak   DW.ref.__gcc_personality_v0
177         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
178         .align  8
179         .type   DW.ref.__gcc_personality_v0, @object
180         .size   DW.ref.__gcc_personality_v0, 8
181 DW.ref.__gcc_personality_v0:
182         .quad   __gcc_personality_v0
183 #endif