Fix some uses of ret in libpthread
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevellock.S
bloba8e15bc941d8e3275187543ddc3db29790b948c1
1 /* Copyright (C) 2002, 2003, 2004, 2006, 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 <pthread-errnos.h>
22 #include <kernel-features.h>
23 #include <lowlevellock.h>
25         .text
27 #ifdef __ASSUME_PRIVATE_FUTEX
28 # define LOAD_PRIVATE_FUTEX_WAIT(reg) \
29         movl    $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
30 # define LOAD_PRIVATE_FUTEX_WAKE(reg) \
31         movl    $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
32 # define LOAD_FUTEX_WAIT(reg) \
33         xorl    $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
34 # define LOAD_FUTEX_WAKE(reg) \
35         xorl    $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
36 #else
37 # if FUTEX_WAIT == 0
38 #  define LOAD_PRIVATE_FUTEX_WAIT(reg) \
39         movl    %gs:PRIVATE_FUTEX, reg
40 # else
41 #  define LOAD_PRIVATE_FUTEX_WAIT(reg) \
42         movl    %gs:PRIVATE_FUTEX, reg ; \
43         orl     $FUTEX_WAIT, reg
44 # endif
45 # define LOAD_PRIVATE_FUTEX_WAKE(reg) \
46         movl    %gs:PRIVATE_FUTEX, reg ; \
47         orl     $FUTEX_WAKE, reg
48 # if FUTEX_WAIT == 0
49 #  define LOAD_FUTEX_WAIT(reg) \
50         xorl    $FUTEX_PRIVATE_FLAG, reg ; \
51         andl    %gs:PRIVATE_FUTEX, reg
52 # else
53 #  define LOAD_FUTEX_WAIT(reg) \
54         xorl    $FUTEX_PRIVATE_FLAG, reg ; \
55         andl    %gs:PRIVATE_FUTEX, reg ; \
56         orl     $FUTEX_WAIT, reg
57 # endif
58 # define LOAD_FUTEX_WAKE(reg) \
59         xorl    $FUTEX_PRIVATE_FLAG, reg ; \
60         andl    %gs:PRIVATE_FUTEX, reg ; \
61         orl     $FUTEX_WAKE, reg
62 #endif
64         .globl  __lll_lock_wait_private
65         .type   __lll_lock_wait_private,@function
66         .hidden __lll_lock_wait_private
67         .align  16
68 __lll_lock_wait_private:
69         cfi_startproc
70         pushl   %edx
71         cfi_adjust_cfa_offset(4)
72         pushl   %ebx
73         cfi_adjust_cfa_offset(4)
74         pushl   %esi
75         cfi_adjust_cfa_offset(4)
76         cfi_offset(%edx, -8)
77         cfi_offset(%ebx, -12)
78         cfi_offset(%esi, -16)
80         movl    $2, %edx
81         movl    %ecx, %ebx
82         xorl    %esi, %esi      /* No timeout.  */
83         LOAD_PRIVATE_FUTEX_WAIT (%ecx)
85         cmpl    %edx, %eax      /* NB:   %edx == 2 */
86         jne 2f
88 1:      movl    $SYS_futex, %eax
89         ENTER_KERNEL
91 2:      movl    %edx, %eax
92         xchgl   %eax, (%ebx)    /* NB:   lock is implied */
94         testl   %eax, %eax
95         jnz     1b
97         popl    %esi
98         cfi_adjust_cfa_offset(-4)
99         cfi_restore(%esi)
100         popl    %ebx
101         cfi_adjust_cfa_offset(-4)
102         cfi_restore(%ebx)
103         popl    %edx
104         cfi_adjust_cfa_offset(-4)
105         cfi_restore(%edx)
106         popl %ecx; nacljmp %ecx
107         cfi_endproc
108         .size   __lll_lock_wait_private,.-__lll_lock_wait_private
110 #ifdef NOT_IN_libc
111         .globl  __lll_lock_wait
112         .type   __lll_lock_wait,@function
113         .hidden __lll_lock_wait
114         .align  16
115 __lll_lock_wait:
116         cfi_startproc
117         pushl   %edx
118         cfi_adjust_cfa_offset(4)
119         pushl   %ebx
120         cfi_adjust_cfa_offset(4)
121         pushl   %esi
122         cfi_adjust_cfa_offset(4)
123         cfi_offset(%edx, -8)
124         cfi_offset(%ebx, -12)
125         cfi_offset(%esi, -16)
127         movl    %edx, %ebx
128         movl    $2, %edx
129         xorl    %esi, %esi      /* No timeout.  */
130         LOAD_FUTEX_WAIT (%ecx)
132         cmpl    %edx, %eax      /* NB:   %edx == 2 */
133         jne 2f
135 1:      movl    $SYS_futex, %eax
136         ENTER_KERNEL
138 2:      movl    %edx, %eax
139         xchgl   %eax, (%ebx)    /* NB:   lock is implied */
141         testl   %eax, %eax
142         jnz     1b
144         popl    %esi
145         cfi_adjust_cfa_offset(-4)
146         cfi_restore(%esi)
147         popl    %ebx
148         cfi_adjust_cfa_offset(-4)
149         cfi_restore(%ebx)
150         popl    %edx
151         cfi_adjust_cfa_offset(-4)
152         cfi_restore(%edx)
153         popl %ecx; nacljmp %ecx
154         cfi_endproc
155         .size   __lll_lock_wait,.-__lll_lock_wait
157         .globl  __lll_timedlock_wait
158         .type   __lll_timedlock_wait,@function
159         .hidden __lll_timedlock_wait
160         .align  16
161 __lll_timedlock_wait:
162         cfi_startproc
163         /* Check for a valid timeout value.  */
164         cmpl    $1000000000, 4(%edx)
165         jae     3f
167         pushl   %edi
168         cfi_adjust_cfa_offset(4)
169         pushl   %esi
170         cfi_adjust_cfa_offset(4)
171         pushl   %ebx
172         cfi_adjust_cfa_offset(4)
173         pushl   %ebp
174         cfi_adjust_cfa_offset(4)
175         cfi_offset(%edi, -8)
176         cfi_offset(%esi, -12)
177         cfi_offset(%ebx, -16)
178         cfi_offset(%ebp, -20)
180         /* Stack frame for the timespec and timeval structs.  */
181         subl    $8, %esp
182         cfi_adjust_cfa_offset(8)
184         movl    %ecx, %ebp
185         movl    %edx, %edi
187         movl    $2, %edx
188         xchgl   %edx, (%ebp)
190         test    %edx, %edx
191         je      6f
194         /* Get current time.  */
195         movl    %esp, %ebx
196         xorl    %ecx, %ecx
197         movl    $__NR_gettimeofday, %eax
198         ENTER_KERNEL
200         /* Compute relative timeout.  */
201         movl    4(%esp), %eax
202         movl    $1000, %edx
203         mul     %edx            /* Milli seconds to nano seconds.  */
204         movl    (%edi), %ecx
205         movl    4(%edi), %edx
206         subl    (%esp), %ecx
207         subl    %eax, %edx
208         jns     4f
209         addl    $1000000000, %edx
210         subl    $1, %ecx
211 4:      testl   %ecx, %ecx
212         js      2f              /* Time is already up.  */
214         /* Store relative timeout.  */
215         movl    %ecx, (%esp)
216         movl    %edx, 4(%esp)
218         /* Futex call.  */
219         movl    %ebp, %ebx
220         movl    $2, %edx
221         movl    %esp, %esi
222         movl    16(%esp), %ecx
223         LOAD_FUTEX_WAIT (%ecx)
224         movl    $SYS_futex, %eax
225         ENTER_KERNEL
227         /* NB: %edx == 2 */
228         xchgl   %edx, (%ebp)
230         testl   %edx, %edx
231         je      6f
233         cmpl    $-ETIMEDOUT, %eax
234         jne     1b
235 2:      movl    $ETIMEDOUT, %edx
237 6:      addl    $8, %esp
238         cfi_adjust_cfa_offset(-8)
239         popl    %ebp
240         cfi_adjust_cfa_offset(-4)
241         cfi_restore(%ebp)
242         popl    %ebx
243         cfi_adjust_cfa_offset(-4)
244         cfi_restore(%ebx)
245         popl    %esi
246         cfi_adjust_cfa_offset(-4)
247         cfi_restore(%esi)
248         popl    %edi
249         cfi_adjust_cfa_offset(-4)
250         cfi_restore(%edi)
251         movl    %edx, %eax
252         popl %ecx; nacljmp %ecx
254 3:      movl    $EINVAL, %eax
255         popl %ecx; nacljmp %ecx
256         cfi_endproc
257         .size   __lll_timedlock_wait,.-__lll_timedlock_wait
258 #endif
260         .globl  __lll_unlock_wake_private
261         .type   __lll_unlock_wake_private,@function
262         .hidden __lll_unlock_wake_private
263         .align  16
264 __lll_unlock_wake_private:
265         cfi_startproc
266         pushl   %ebx
267         cfi_adjust_cfa_offset(4)
268         pushl   %ecx
269         cfi_adjust_cfa_offset(4)
270         pushl   %edx
271         cfi_adjust_cfa_offset(4)
272         cfi_offset(%ebx, -8)
273         cfi_offset(%ecx, -12)
274         cfi_offset(%edx, -16)
276         movl    %eax, %ebx
277         movl    $0, (%eax)
278         LOAD_PRIVATE_FUTEX_WAKE (%ecx)
279         movl    $1, %edx        /* Wake one thread.  */
280         movl    $SYS_futex, %eax
281         ENTER_KERNEL
283         popl    %edx
284         cfi_adjust_cfa_offset(-4)
285         cfi_restore(%edx)
286         popl    %ecx
287         cfi_adjust_cfa_offset(-4)
288         cfi_restore(%ecx)
289         popl    %ebx
290         cfi_adjust_cfa_offset(-4)
291         cfi_restore(%ebx)
292         popl %ecx; nacljmp %ecx
293         cfi_endproc
294         .size   __lll_unlock_wake_private,.-__lll_unlock_wake_private
296 #ifdef NOT_IN_libc
297         .globl  __lll_unlock_wake
298         .type   __lll_unlock_wake,@function
299         .hidden __lll_unlock_wake
300         .align  16
301 __lll_unlock_wake:
302         cfi_startproc
303         pushl   %ebx
304         cfi_adjust_cfa_offset(4)
305         pushl   %ecx
306         cfi_adjust_cfa_offset(4)
307         pushl   %edx
308         cfi_adjust_cfa_offset(4)
309         cfi_offset(%ebx, -8)
310         cfi_offset(%ecx, -12)
311         cfi_offset(%edx, -16)
313         movl    %eax, %ebx
314         movl    $0, (%eax)
315         LOAD_FUTEX_WAKE (%ecx)
316         movl    $1, %edx        /* Wake one thread.  */
317         movl    $SYS_futex, %eax
318         ENTER_KERNEL
320         popl    %edx
321         cfi_adjust_cfa_offset(-4)
322         cfi_restore(%edx)
323         popl    %ecx
324         cfi_adjust_cfa_offset(-4)
325         cfi_restore(%ecx)
326         popl    %ebx
327         cfi_adjust_cfa_offset(-4)
328         cfi_restore(%ebx)
329         popl %ecx; nacljmp %ecx
330         cfi_endproc
331         .size   __lll_unlock_wake,.-__lll_unlock_wake
333         .globl  __lll_timedwait_tid
334         .type   __lll_timedwait_tid,@function
335         .hidden __lll_timedwait_tid
336         .align  16
337 __lll_timedwait_tid:
338         pushl   %edi
339         pushl   %esi
340         pushl   %ebx
341         pushl   %ebp
343         movl    %eax, %ebp
344         movl    %edx, %edi
345         subl    $8, %esp
347         /* Get current time.  */
348 2:      movl    %esp, %ebx
349         xorl    %ecx, %ecx
350         movl    $__NR_gettimeofday, %eax
351         ENTER_KERNEL
353         /* Compute relative timeout.  */
354         movl    4(%esp), %eax
355         movl    $1000, %edx
356         mul     %edx            /* Milli seconds to nano seconds.  */
357         movl    (%edi), %ecx
358         movl    4(%edi), %edx
359         subl    (%esp), %ecx
360         subl    %eax, %edx
361         jns     5f
362         addl    $1000000000, %edx
363         subl    $1, %ecx
364 5:      testl   %ecx, %ecx
365         js      6f              /* Time is already up.  */
367         movl    %ecx, (%esp)    /* Store relative timeout.  */
368         movl    %edx, 4(%esp)
370         movl    (%ebp), %edx
371         testl   %edx, %edx
372         jz      4f
374         movl    %esp, %esi
375         /* XXX The kernel so far uses global futex for the wakeup at
376            all times.  */
377         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
378         movl    %ebp, %ebx
379         movl    $SYS_futex, %eax
380         ENTER_KERNEL
382         cmpl    $0, (%ebx)
383         jne     1f
384 4:      xorl    %eax, %eax
386 3:      addl    $8, %esp
387         popl    %ebp
388         popl    %ebx
389         popl    %esi
390         popl    %edi
391         popl %ecx; nacljmp %ecx
393 1:      cmpl    $-ETIMEDOUT, %eax
394         jne     2b
395 6:      movl    $ETIMEDOUT, %eax
396         jmp     3b
397         .size   __lll_timedwait_tid,.-__lll_timedwait_tid
398 #endif