OSDN Git Service

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