fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_wait.S
1 /* Copyright (C) 2002, 2003, 2005, 2007 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 <shlib-compat.h>
22 #include <pthread-errnos.h>
23 #include <structsem.h>
24 #include <lowlevellock.h>
25
26
27 #if VALUE != 0
28 # error "code needs to be rewritten for VALUE != 0"
29 #endif
30
31         .text
32
33         .globl  __new_sem_wait
34         .type   __new_sem_wait,@function
35         .align  16
36 __new_sem_wait:
37 .LSTARTCODE:
38         pushl   %ebx
39 .Lpush_ebx:
40         pushl   %esi
41 .Lpush_esi:
42         subl    $4, %esp
43 .Lsub_esp:
44
45         movl    16(%esp), %ebx
46
47         movl    (%ebx), %eax
48 2:      testl   %eax, %eax
49         je      1f
50
51         leal    -1(%eax), %edx
52         LOCK
53         cmpxchgl %edx, (%ebx)
54         jne     2b
55 7:      xorl    %eax, %eax
56
57 9:      movl    4(%esp), %esi
58         movl    8(%esp), %ebx
59         addl    $12, %esp
60 .Ladd_esp:
61         ret
62
63 .Lafter_ret:
64 1:      LOCK
65         incl    NWAITERS(%ebx)
66
67 .LcleanupSTART:
68 6:      call    __pthread_enable_asynccancel
69         movl    %eax, (%esp)
70
71 #if FUTEX_WAIT == 0
72         movl    PRIVATE(%ebx), %ecx
73 #else
74         movl    $FUTEX_WAIT, %ecx
75         orl     PRIVATE(%ebx), %ecx
76 #endif
77         xorl    %esi, %esi
78         xorl    %edx, %edx
79         movl    $SYS_futex, %eax
80         ENTER_KERNEL
81         movl    %eax, %esi
82
83         movl    (%esp), %eax
84         call    __pthread_disable_asynccancel
85 .LcleanupEND:
86
87         testl   %esi, %esi
88         je      3f
89         cmpl    $-EWOULDBLOCK, %esi
90         jne     4f
91
92 3:
93         movl    (%ebx), %eax
94 5:      testl   %eax, %eax
95         je      6b
96
97         leal    -1(%eax), %edx
98         LOCK
99         cmpxchgl %edx, (%ebx)
100         jne     5b
101
102         LOCK
103         decl    NWAITERS(%ebx)
104         jmp     7b
105
106 4:      LOCK
107         decl    NWAITERS(%ebx)
108
109         negl    %esi
110 #ifdef PIC
111         call    __i686.get_pc_thunk.bx
112 #else
113         movl    $8f, %ebx
114 8:
115 #endif
116         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
117 #if USE___THREAD
118 # ifdef NO_TLS_DIRECT_SEG_REFS
119         movl    errno@gotntpoff(%ebx), %edx
120         addl    %gs:0, %edx
121         movl    %esi, (%edx)
122 # else
123         movl    errno@gotntpoff(%ebx), %edx
124         movl    %esi, %gs:(%edx)
125 # endif
126 #else
127         call    __errno_location@plt
128         movl    %esi, (%eax)
129 #endif
130         orl     $-1, %eax
131
132         jmp     9b
133         .size   __new_sem_wait,.-__new_sem_wait
134         versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
135
136
137         .type   sem_wait_cleanup,@function
138 sem_wait_cleanup:
139         LOCK
140         decl    NWAITERS(%ebx)
141         movl    %eax, (%esp)
142 .LcallUR:
143         call    _Unwind_Resume@PLT
144         hlt
145 .LENDCODE:
146         .size   sem_wait_cleanup,.-sem_wait_cleanup
147
148
149         .section .gcc_except_table,"a",@progbits
150 .LexceptSTART:
151         .byte   0xff                            # @LPStart format (omit)
152         .byte   0xff                            # @TType format (omit)
153         .byte   0x01                            # call-site format
154                                                 # DW_EH_PE_uleb128
155         .uleb128 .Lcstend-.Lcstbegin
156 .Lcstbegin:
157         .uleb128 .LcleanupSTART-.LSTARTCODE
158         .uleb128 .LcleanupEND-.LcleanupSTART
159         .uleb128 sem_wait_cleanup-.LSTARTCODE
160         .uleb128  0
161         .uleb128 .LcallUR-.LSTARTCODE
162         .uleb128 .LENDCODE-.LcallUR
163         .uleb128 0
164         .uleb128  0
165 .Lcstend:
166
167
168         .section .eh_frame,"a",@progbits
169 .LSTARTFRAME:
170         .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
171 .LSTARTCIE:
172         .long   0                               # CIE ID.
173         .byte   1                               # Version number.
174 #ifdef SHARED
175         .string "zPLR"                          # NUL-terminated augmentation
176                                                 # string.
177 #else
178         .string "zPL"                           # NUL-terminated augmentation
179                                                 # string.
180 #endif
181         .uleb128 1                              # Code alignment factor.
182         .sleb128 -4                             # Data alignment factor.
183         .byte   8                               # Return address register
184                                                 # column.
185 #ifdef SHARED
186         .uleb128 7                              # Augmentation value length.
187         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
188                                                 # + DW_EH_PE_sdata4
189                                                 # + DW_EH_PE_indirect
190         .long   DW.ref.__gcc_personality_v0-.
191         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
192                                                 # + DW_EH_PE_sdata4.
193         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
194                                                 # + DW_EH_PE_sdata4.
195 #else
196         .uleb128 6                              # Augmentation value length.
197         .byte   0x0                             # Personality: absolute
198         .long   __gcc_personality_v0
199         .byte   0x0                             # LSDA Encoding: absolute
200 #endif
201         .byte 0x0c                              # DW_CFA_def_cfa
202         .uleb128 4
203         .uleb128 4
204         .byte   0x88                            # DW_CFA_offset, column 0x10
205         .uleb128 1
206         .align 4
207 .LENDCIE:
208
209         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
210 .LSTARTFDE:
211         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
212 #ifdef SHARED
213         .long   .LSTARTCODE-.                   # PC-relative start address
214                                                 # of the code.
215 #else
216         .long   .LSTARTCODE                     # Start address of the code.
217 #endif
218         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
219         .uleb128 4                              # Augmentation size
220 #ifdef SHARED
221         .long   .LexceptSTART-.
222 #else
223         .long   .LexceptSTART
224 #endif
225
226         .byte   4                               # DW_CFA_advance_loc4
227         .long   .Lpush_ebx-.LSTARTCODE
228         .byte   14                              # DW_CFA_def_cfa_offset
229         .uleb128 8
230         .byte   0x83                            # DW_CFA_offset %ebx
231         .uleb128 2
232         .byte   4                               # DW_CFA_advance_loc4
233         .long   .Lpush_esi-.Lpush_ebx
234         .byte   14                              # DW_CFA_def_cfa_offset
235         .uleb128 12
236         .byte   0x86                            # DW_CFA_offset %esi
237         .uleb128 3
238         .byte   4                               # DW_CFA_advance_loc4
239         .long   .Lsub_esp-.Lpush_esi
240         .byte   14                              # DW_CFA_def_cfa_offset
241         .uleb128 16
242         .byte   4                               # DW_CFA_advance_loc4
243         .long   .Ladd_esp-.Lsub_esp
244         .byte   14                              # DW_CFA_def_cfa_offset
245         .uleb128 4
246         .byte   0xc3                            # DW_CFA_restore %ebx
247         .byte   0xc6                            # DW_CFA_restore %esi
248         .byte   4                               # DW_CFA_advance_loc4
249         .long   .Lafter_ret-.Ladd_esp
250         .byte   14                              # DW_CFA_def_cfa_offset
251         .uleb128 16
252         .byte   0x83                            # DW_CFA_offset %ebx
253         .uleb128 2
254         .byte   0x86                            # DW_CFA_offset %esi
255         .uleb128 3
256         .align  4
257 .LENDFDE:
258
259
260 #ifdef SHARED
261         .hidden DW.ref.__gcc_personality_v0
262         .weak   DW.ref.__gcc_personality_v0
263         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
264         .align  4
265         .type   DW.ref.__gcc_personality_v0, @object
266         .size   DW.ref.__gcc_personality_v0, 4
267 DW.ref.__gcc_personality_v0:
268         .long   __gcc_personality_v0
269 #endif
270
271
272 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
273         .section ".text.compat", "ax"
274         .global __old_sem_wait
275         .type   __old_sem_wait,@function
276         .align  16
277         cfi_startproc
278 __old_sem_wait:
279         pushl   %ebx
280         cfi_adjust_cfa_offset(4)
281         pushl   %esi
282         cfi_adjust_cfa_offset(4)
283         subl    $4, %esp
284         cfi_adjust_cfa_offset(4)
285
286         movl    16(%esp), %ebx
287         cfi_offset(ebx, -8)
288
289         cfi_offset(esi, -12)
290 3:      movl    (%ebx), %eax
291 2:      testl   %eax, %eax
292         je      1f
293
294         leal    -1(%eax), %edx
295         LOCK
296         cmpxchgl %edx, (%ebx)
297         jne     2b
298         xorl    %eax, %eax
299
300 5:      movl    4(%esp), %esi
301         movl    8(%esp), %ebx
302         addl    $12, %esp
303         cfi_restore(ebx)
304         cfi_restore(esi)
305         cfi_adjust_cfa_offset(-12)
306         ret
307
308         cfi_adjust_cfa_offset(12)
309         cfi_offset(ebx, -8)
310         cfi_offset(esi, -12)
311 1:      call    __pthread_enable_asynccancel
312         movl    %eax, (%esp)
313
314         xorl    %esi, %esi
315         movl    $SYS_futex, %eax
316         movl    %esi, %ecx
317         movl    %esi, %edx
318         ENTER_KERNEL
319         movl    %eax, %esi
320
321         movl    (%esp), %eax
322         call    __pthread_disable_asynccancel
323
324         testl   %esi, %esi
325         je      3b
326         cmpl    $-EWOULDBLOCK, %esi
327         je      3b
328         negl    %esi
329 #ifdef PIC
330         call    __i686.get_pc_thunk.bx
331 #else
332         movl    $4f, %ebx
333 4:
334 #endif
335         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
336 #if USE___THREAD
337 # ifdef NO_TLS_DIRECT_SEG_REFS
338         movl    errno@gotntpoff(%ebx), %edx
339         addl    %gs:0, %edx
340         movl    %esi, (%edx)
341 # else
342         movl    errno@gotntpoff(%ebx), %edx
343         movl    %esi, %gs:(%edx)
344 # endif
345 #else
346         call    __errno_location@plt
347         movl    %esi, (%eax)
348 #endif
349         orl     $-1, %eax
350         jmp     5b
351         cfi_endproc
352         .size   __old_sem_wait,.-__old_sem_wait
353         compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0)
354 #endif