* sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Add private futex
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / sem_timedwait.S
blob57b5b58186a699245825cd7a70c69c517c02fb5d
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_WAIT              0
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 #if FUTEX_WAIT == 0
112         movl    PRIVATE(%ebx), %ecx
113 #else
114         movl    $FUTEX_WAIT, %ecx
115         orl     PRIVATE(%ebx), %ecx
116 #endif
117         movl    %esp, %esi
118         xorl    %edx, %edx
119         movl    $SYS_futex, %eax
120         ENTER_KERNEL
121         movl    %eax, %esi
123         movl    8(%esp), %eax
124         call    __pthread_disable_asynccancel
125 .LcleanupEND:
127         testl   %esi, %esi
128         je      9f
129         cmpl    $-EWOULDBLOCK, %esi
130         jne     3f
132 9:      movl    (%ebx), %eax
133 8:      testl   %eax, %eax
134         je      7b
136         leal    -1(%eax), %ecx
137         LOCK
138         cmpxchgl %ecx, (%ebx)
139         jne     8b
141         xorl    %eax, %eax
143 10:     LOCK
144         decl    NWAITERS(%ebx)
146         addl    $12, %esp
147 .Ladd_esp:
148         popl    %ebx
149 .Lpop_ebx:
150         popl    %edi
151 .Lpop_edi:
152         popl    %esi
153 .Lpop_esi:
154         ret
156 .Lafter_ret:
157 3:      negl    %esi
159 #ifdef PIC
160         call    __i686.get_pc_thunk.bx
161 #else
162         movl    $4f, %ebx
164 #endif
165         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
166 #if USE___THREAD
167 # ifdef NO_TLS_DIRECT_SEG_REFS
168         movl    errno@gotntpoff(%ebx), %edx
169         addl    %gs:0, %edx
170         movl    %esi, (%edx)
171 # else
172         movl    errno@gotntpoff(%ebx), %edx
173         movl    %esi, %gs:(%edx)
174 # endif
175 #else
176         call    __errno_location@plt
177         movl    %esi, (%eax)
178 #endif
180         movl    28(%esp), %ebx  /* Load semaphore address.  */
181         orl     $-1, %eax
182         jmp     10b
183         .size   sem_timedwait,.-sem_timedwait
186         .type   sem_wait_cleanup,@function
187 sem_wait_cleanup:
188         LOCK
189         decl    NWAITERS(%ebx)
190         movl    %eax, (%esp)
191 .LcallUR:
192         call    _Unwind_Resume@PLT
193         hlt
194 .LENDCODE:
195         .size   sem_wait_cleanup,.-sem_wait_cleanup
198         .section .gcc_except_table,"a",@progbits
199 .LexceptSTART:
200         .byte   0xff                            # @LPStart format (omit)
201         .byte   0xff                            # @TType format (omit)
202         .byte   0x01                            # call-site format
203                                                 # DW_EH_PE_uleb128
204         .uleb128 .Lcstend-.Lcstbegin
205 .Lcstbegin:
206         .uleb128 .LcleanupSTART-.LSTARTCODE
207         .uleb128 .LcleanupEND-.LcleanupSTART
208         .uleb128 sem_wait_cleanup-.LSTARTCODE
209         .uleb128  0
210         .uleb128 .LcallUR-.LSTARTCODE
211         .uleb128 .LENDCODE-.LcallUR
212         .uleb128 0
213         .uleb128  0
214 .Lcstend:
217         .section .eh_frame,"a",@progbits
218 .LSTARTFRAME:
219         .long   .LENDCIE-.LSTARTCIE             # Length of the CIE.
220 .LSTARTCIE:
221         .long   0                               # CIE ID.
222         .byte   1                               # Version number.
223 #ifdef SHARED
224         .string "zPLR"                          # NUL-terminated augmentation
225                                                 # string.
226 #else
227         .string "zPL"                           # NUL-terminated augmentation
228                                                 # string.
229 #endif
230         .uleb128 1                              # Code alignment factor.
231         .sleb128 -4                             # Data alignment factor.
232         .byte   8                               # Return address register
233                                                 # column.
234 #ifdef SHARED
235         .uleb128 7                              # Augmentation value length.
236         .byte   0x9b                            # Personality: DW_EH_PE_pcrel
237                                                 # + DW_EH_PE_sdata4
238                                                 # + DW_EH_PE_indirect
239         .long   DW.ref.__gcc_personality_v0-.
240         .byte   0x1b                            # LSDA Encoding: DW_EH_PE_pcrel
241                                                 # + DW_EH_PE_sdata4.
242         .byte   0x1b                            # FDE Encoding: DW_EH_PE_pcrel
243                                                 # + DW_EH_PE_sdata4.
244 #else
245         .uleb128 6                              # Augmentation value length.
246         .byte   0x0                             # Personality: absolute
247         .long   __gcc_personality_v0
248         .byte   0x0                             # LSDA Encoding: absolute
249 #endif
250         .byte 0x0c                              # DW_CFA_def_cfa
251         .uleb128 4
252         .uleb128 4
253         .byte   0x88                            # DW_CFA_offset, column 0x10
254         .uleb128 1
255         .align 4
256 .LENDCIE:
258         .long   .LENDFDE-.LSTARTFDE             # Length of the FDE.
259 .LSTARTFDE:
260         .long   .LSTARTFDE-.LSTARTFRAME         # CIE pointer.
261 #ifdef SHARED
262         .long   .LSTARTCODE-.                   # PC-relative start address
263                                                 # of the code.
264 #else
265         .long   .LSTARTCODE                     # Start address of the code.
266 #endif
267         .long   .LENDCODE-.LSTARTCODE           # Length of the code.
268         .uleb128 4                              # Augmentation size
269 #ifdef SHARED
270         .long   .LexceptSTART-.
271 #else
272         .long   .LexceptSTART
273 #endif
275         .byte   4                               # DW_CFA_advance_loc4
276         .long   .Lpush_esi-.LSTARTCODE
277         .byte   14                              # DW_CFA_def_cfa_offset
278         .uleb128 8
279         .byte   0x86                            # DW_CFA_offset %esi
280         .uleb128 2
281         .byte   4                               # DW_CFA_advance_loc4
282         .long   .Lpush_edi-.Lpush_esi
283         .byte   14                              # DW_CFA_def_cfa_offset
284         .uleb128 12
285         .byte   0x87                            # DW_CFA_offset %edi
286         .uleb128 3
287         .byte   4                               # DW_CFA_advance_loc4
288         .long   .Lpush_ebx-.Lpush_edi
289         .byte   14                              # DW_CFA_def_cfa_offset
290         .uleb128 16
291         .byte   0x83                            # DW_CFA_offset %ebx
292         .uleb128 4
293         .byte   4                               # DW_CFA_advance_loc4
294         .long   .Lsub_esp-.Lpush_ebx
295         .byte   14                              # DW_CFA_def_cfa_offset
296         .uleb128 28
297         .byte   4                               # DW_CFA_advance_loc4
298         .long   .Ladd_esp-.Lsub_esp
299         .byte   14                              # DW_CFA_def_cfa_offset
300         .uleb128 16
301         .byte   4                               # DW_CFA_advance_loc4
302         .long   .Lpop_ebx-.Ladd_esp
303         .byte   14                              # DW_CFA_def_cfa_offset
304         .uleb128 12
305         .byte   0xc3                            # DW_CFA_restore %ebx
306         .byte   4                               # DW_CFA_advance_loc4
307         .long   .Lpop_edi-.Lpop_ebx
308         .byte   14                              # DW_CFA_def_cfa_offset
309         .uleb128 8
310         .byte   0xc7                            # DW_CFA_restore %edi
311         .byte   4                               # DW_CFA_advance_loc4
312         .long   .Lpop_esi-.Lpop_edi
313         .byte   14                              # DW_CFA_def_cfa_offset
314         .uleb128 4
315         .byte   0xc6                            # DW_CFA_restore %esi
316         .byte   4                               # DW_CFA_advance_loc4
317         .long   .Lafter_ret-.Lpop_esi
318         .byte   14                              # DW_CFA_def_cfa_offset
319         .uleb128 28
320         .byte   0x86                            # DW_CFA_offset %esi
321         .uleb128 2
322         .byte   0x87                            # DW_CFA_offset %edi
323         .uleb128 3
324         .byte   0x83                            # DW_CFA_offset %ebx
325         .uleb128 4
326         .align  4
327 .LENDFDE:
330 #ifdef SHARED
331         .hidden DW.ref.__gcc_personality_v0
332         .weak   DW.ref.__gcc_personality_v0
333         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
334         .align  4
335         .type   DW.ref.__gcc_personality_v0, @object
336         .size   DW.ref.__gcc_personality_v0, 4
337 DW.ref.__gcc_personality_v0:
338         .long   __gcc_personality_v0
339 #endif