* semaphoreP.h: Declare __old_sem_init and __old_sem_wait.
[glibc/pb-stable.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_timedwait.S
blob3677ab3bf9fdd341c522635e2b80e2370ea84d36
1 /* Copyright (C) 2002, 2003, 2004, 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.
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.
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.
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.  */
20 #include <sysdep.h>
21 #include <shlib-compat.h>
22 #include <pthread-errnos.h>
23 #include <structsem.h>
25 #ifndef UP
26 # define LOCK lock
27 #else
28 # define
29 #endif
31 #define SYS_gettimeofday        __NR_gettimeofday
32 #define SYS_futex               240
33 #define FUTEX_WAKE              1
36 #if VALUE != 0
37 # error "code needs to be rewritten for VALUE != 0"
38 #endif
41         .text
43         .globl  sem_timedwait
44         .type   sem_timedwait,@function
45         .align  16
46 sem_timedwait:
47 .LSTARTCODE:
48         movl    4(%esp), %ecx
50         movl    (%ecx), %eax
51 2:      testl   %eax, %eax
52         je      1f
54         leal    -1(%eax), %edx
55         LOCK
56         cmpxchgl %edx, (%ecx)
57         jne     2b
59         xorl    %eax, %eax
60         ret
62         /* Check whether the timeout value is valid.  */
63 1:      pushl   %esi
64 .Lpush_esi:
65         pushl   %edi
66 .Lpush_edi:
67         pushl   %ebx
68 .Lpush_ebx:
69         subl    $12, %esp
70 .Lsub_esp:
72         movl    32(%esp), %edi
74         /* Check for invalid nanosecond field.  */
75         cmpl    $1000000000, 4(%edi)
76         movl    $EINVAL, %esi
77         jae     6f
79         LOCK
80         incl    NWAITERS(%ecx)
82 7:      xorl    %ecx, %ecx
83         movl    %esp, %ebx
84         movl    %ecx, %edx
85         movl    $SYS_gettimeofday, %eax
86         ENTER_KERNEL
88         /* Compute relative timeout.  */
89         movl    4(%esp), %eax
90         movl    $1000, %edx
91         mul     %edx            /* Milli seconds to nano seconds.  */
92         movl    (%edi), %ecx
93         movl    4(%edi), %edx
94         subl    (%esp), %ecx
95         subl    %eax, %edx
96         jns     5f
97         addl    $1000000000, %edx
98         subl    $1, %ecx
99 5:      testl   %ecx, %ecx
100         movl    $ETIMEDOUT, %esi
101         js      6f              /* Time is already up.  */
103         movl    %ecx, (%esp)    /* Store relative timeout.  */
104         movl    %edx, 4(%esp)
106 .LcleanupSTART:
107         call    __pthread_enable_asynccancel
108         movl    %eax, 8(%esp)
110         movl    28(%esp), %ebx  /* Load semaphore address.  */
111         xorl    %ecx, %ecx
112         movl    %esp, %esi
113         movl    $SYS_futex, %eax
114         xorl    %edx, %edx
115         ENTER_KERNEL
116         movl    %eax, %esi
118         movl    8(%esp), %eax
119         call    __pthread_disable_asynccancel
120 .LcleanupEND:
122         testl   %esi, %esi
123         je      9f
124         cmpl    $-EWOULDBLOCK, %esi
125         jne     3f
127 9:      movl    (%ebx), %eax
128 8:      testl   %eax, %eax
129         je      7b
131         leal    -1(%eax), %ecx
132         LOCK
133         cmpxchgl %ecx, (%ebx)
134         jne     8b
136         xorl    %eax, %eax
138 10:     LOCK
139         decl    NWAITERS(%ebx)
141         addl    $12, %esp
142 .Ladd_esp:
143         popl    %ebx
144 .Lpop_ebx:
145         popl    %edi
146 .Lpop_edi:
147         popl    %esi
148 .Lpop_esi:
149         ret
151 .Lafter_ret:
152 3:      negl    %esi
154 #ifdef PIC
155         call    __i686.get_pc_thunk.bx
156 #else
157         movl    $4f, %ebx
159 #endif
160         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
161 #if USE___THREAD
162 # ifdef NO_TLS_DIRECT_SEG_REFS
163         movl    errno@gotntpoff(%ebx), %edx
164         addl    %gs:0, %edx
165         movl    %esi, (%edx)
166 # else
167         movl    errno@gotntpoff(%ebx), %edx
168         movl    %esi, %gs:(%edx)
169 # endif
170 #else
171         call    __errno_location@plt
172         movl    %esi, (%eax)
173 #endif
175         movl    28(%esp), %ebx  /* Load semaphore address.  */
176         orl     $-1, %eax
177         jmp     10b
178         .size   sem_timedwait,.-sem_timedwait
181         .type   sem_wait_cleanup,@function
182 sem_wait_cleanup:
183         LOCK
184         decl    NWAITERS(%ebx)
185         movl    %eax, (%esp)
186 .LcallUR:
187         call    _Unwind_Resume@PLT
188         hlt
189 .LENDCODE:
190         .size   sem_wait_cleanup,.-sem_wait_cleanup
193         .section .gcc_except_table,"a",@progbits
194 .LexceptSTART:
195         .byte   0xff                            # @LPStart format (omit)
196         .byte   0xff                            # @TType format (omit)
197         .byte   0x01                            # call-site format
198                                                 # DW_EH_PE_uleb128
199         .uleb128 .Lcstend-.Lcstbegin
200 .Lcstbegin:
201         .uleb128 .LcleanupSTART-.LSTARTCODE
202         .uleb128 .LcleanupEND-.LcleanupSTART
203         .uleb128 sem_wait_cleanup-.LSTARTCODE
204         .uleb128  0
205         .uleb128 .LcallUR-.LSTARTCODE
206         .uleb128 .LENDCODE-.LcallUR
207         .uleb128 0
208         .uleb128  0
209 .Lcstend:
212         .section .eh_frame,"a",@progbits
213 .LSTARTFRAME:
214         .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
215 .LSTARTCIE:
216         .long   0                               # CIE ID.
217         .byte   1                               # Version number.
218 #ifdef SHARED
219         .string "zPLR"                          # NUL-terminated augmentation
220                                                 # string.
221 #else
222         .string "zPL"                           # NUL-terminated augmentation
223                                                 # string.
224 #endif
225         .uleb128 1                              # Code alignment factor.
226         .sleb128 -4                             # Data alignment factor.
227         .byte   8                               # Return address register
228                                                 # column.
229 #ifdef SHARED
230         .uleb128 7                              # Augmentation value length.
231         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
232                                                 # + DW_EH_PE_sdata4
233                                                 # + DW_EH_PE_indirect
234         .long   DW.ref.__gcc_personality_v0-.
235         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
236                                                 # + DW_EH_PE_sdata4.
237         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
238                                                 # + DW_EH_PE_sdata4.
239 #else
240         .uleb128 6                              # Augmentation value length.
241         .byte   0x0                             # Personality: absolute
242         .long   __gcc_personality_v0
243         .byte   0x0                             # LSDA Encoding: absolute
244 #endif
245         .byte 0x0c                              # DW_CFA_def_cfa
246         .uleb128 4
247         .uleb128 4
248         .byte   0x88                            # DW_CFA_offset, column 0x10
249         .uleb128 1
250         .align 4
251 .LENDCIE:
253         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
254 .LSTARTFDE:
255         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
256 #ifdef SHARED
257         .long   .LSTARTCODE-.                   # PC-relative start address
258                                                 # of the code.
259 #else
260         .long   .LSTARTCODE                     # Start address of the code.
261 #endif
262         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
263         .uleb128 4                              # Augmentation size
264 #ifdef SHARED
265         .long   .LexceptSTART-.
266 #else
267         .long   .LexceptSTART
268 #endif
270         .byte   4                               # DW_CFA_advance_loc4
271         .long   .Lpush_esi-.LSTARTCODE
272         .byte   14                              # DW_CFA_def_cfa_offset
273         .uleb128 8
274         .byte   0x86                            # DW_CFA_offset %esi
275         .uleb128 2
276         .byte   4                               # DW_CFA_advance_loc4
277         .long   .Lpush_edi-.Lpush_esi
278         .byte   14                              # DW_CFA_def_cfa_offset
279         .uleb128 12
280         .byte   0x87                            # DW_CFA_offset %edi
281         .uleb128 3
282         .byte   4                               # DW_CFA_advance_loc4
283         .long   .Lpush_ebx-.Lpush_edi
284         .byte   14                              # DW_CFA_def_cfa_offset
285         .uleb128 16
286         .byte   0x83                            # DW_CFA_offset %ebx
287         .uleb128 4
288         .byte   4                               # DW_CFA_advance_loc4
289         .long   .Lsub_esp-.Lpush_ebx
290         .byte   14                              # DW_CFA_def_cfa_offset
291         .uleb128 28
292         .byte   4                               # DW_CFA_advance_loc4
293         .long   .Ladd_esp-.Lsub_esp
294         .byte   14                              # DW_CFA_def_cfa_offset
295         .uleb128 16
296         .byte   4                               # DW_CFA_advance_loc4
297         .long   .Lpop_ebx-.Ladd_esp
298         .byte   14                              # DW_CFA_def_cfa_offset
299         .uleb128 12
300         .byte   0xc3                            # DW_CFA_restore %ebx
301         .byte   4                               # DW_CFA_advance_loc4
302         .long   .Lpop_edi-.Lpop_ebx
303         .byte   14                              # DW_CFA_def_cfa_offset
304         .uleb128 8
305         .byte   0xc7                            # DW_CFA_restore %edi
306         .byte   4                               # DW_CFA_advance_loc4
307         .long   .Lpop_esi-.Lpop_edi
308         .byte   14                              # DW_CFA_def_cfa_offset
309         .uleb128 4
310         .byte   0xc6                            # DW_CFA_restore %esi
311         .byte   4                               # DW_CFA_advance_loc4
312         .long   .Lafter_ret-.Lpop_esi
313         .byte   14                              # DW_CFA_def_cfa_offset
314         .uleb128 28
315         .byte   0x86                            # DW_CFA_offset %esi
316         .uleb128 2
317         .byte   0x87                            # DW_CFA_offset %edi
318         .uleb128 3
319         .byte   0x83                            # DW_CFA_offset %ebx
320         .uleb128 4
321         .align  4
322 .LENDFDE:
325 #ifdef SHARED
326         .hidden DW.ref.__gcc_personality_v0
327         .weak   DW.ref.__gcc_personality_v0
328         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
329         .align  4
330         .type   DW.ref.__gcc_personality_v0, @object
331         .size   DW.ref.__gcc_personality_v0, 4
332 DW.ref.__gcc_personality_v0:
333         .long   __gcc_personality_v0
334 #endif