OSDN Git Service

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