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