2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevelrobustlock.S
blob73d8bc4cccef85ecd00812c2638737e33c213b43
1 /* Copyright (C) 2002, 2003, 2004, 2006 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 <lowlevelrobustlock.h>
24         .text
26 #ifndef LOCK
27 # ifdef UP
28 #  define LOCK
29 # else
30 #  define LOCK lock
31 # endif
32 #endif
34 #define SYS_gettimeofday        __NR_gettimeofday
35 #define SYS_futex               240
36 #define FUTEX_WAIT              0
37 #define FUTEX_WAKE              1
38 #define FUTEX_WAITERS           0x80000000
39 #define FUTEX_OWNER_DIED        0x40000000
42         .globl  __lll_robust_mutex_lock_wait
43         .type   __lll_robust_mutex_lock_wait,@function
44         .hidden __lll_robust_mutex_lock_wait
45         .align  16
46 __lll_robust_mutex_lock_wait:
47         cfi_startproc
48         pushl   %edx
49         cfi_adjust_cfa_offset(4)
50         pushl   %ebx
51         cfi_adjust_cfa_offset(4)
52         pushl   %esi
53         cfi_adjust_cfa_offset(4)
54         cfi_offset(%edx, -8)
55         cfi_offset(%ebx, -12)
56         cfi_offset(%esi, -16)
58         movl    %ecx, %ebx
59         xorl    %esi, %esi      /* No timeout.  */
60         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
62 4:      movl    %eax, %edx
63         orl     $FUTEX_WAITERS, %edx
65         testl   $FUTEX_OWNER_DIED, %eax
66         jnz     3f
68         cmpl    %edx, %eax      /* NB:   %edx == 2 */
69         je      1f
71         LOCK
72         cmpxchgl %edx, (%ebx)
73         jnz     2f
75 1:      movl    $SYS_futex, %eax
76         ENTER_KERNEL
78         movl    (%ebx), %eax
80 2:      test    %eax, %eax
81         jne     4b
83         movl    %gs:TID, %edx
84         orl     $FUTEX_WAITERS, %edx
85         LOCK
86         cmpxchgl %edx, (%ebx)
87         jnz     4b
88         /* NB:   %eax == 0 */
90 3:      popl    %esi
91         cfi_adjust_cfa_offset(-4)
92         cfi_restore(%esi)
93         popl    %ebx
94         cfi_adjust_cfa_offset(-4)
95         cfi_restore(%ebx)
96         popl    %edx
97         cfi_adjust_cfa_offset(-4)
98         cfi_restore(%edx)
99         ret
100         cfi_endproc
101         .size   __lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
104         .globl  __lll_robust_mutex_timedlock_wait
105         .type   __lll_robust_mutex_timedlock_wait,@function
106         .hidden __lll_robust_mutex_timedlock_wait
107         .align  16
108 __lll_robust_mutex_timedlock_wait:
109         cfi_startproc
110         /* Check for a valid timeout value.  */
111         cmpl    $1000000000, 4(%edx)
112         jae     3f
114         pushl   %edi
115         cfi_adjust_cfa_offset(4)
116         pushl   %esi
117         cfi_adjust_cfa_offset(4)
118         pushl   %ebx
119         cfi_adjust_cfa_offset(4)
120         pushl   %ebp
121         cfi_adjust_cfa_offset(4)
122         cfi_offset(%edi, -8)
123         cfi_offset(%esi, -12)
124         cfi_offset(%ebx, -16)
125         cfi_offset(%ebp, -20)
127         /* Stack frame for the timespec and timeval structs.  */
128         subl    $12, %esp
129         cfi_adjust_cfa_offset(12)
131         movl    %ecx, %ebp
132         movl    %edx, %edi
134 1:      movl    %eax, 8(%esp)
136         /* Get current time.  */
137         movl    %esp, %ebx
138         xorl    %ecx, %ecx
139         movl    $SYS_gettimeofday, %eax
140         ENTER_KERNEL
142         /* Compute relative timeout.  */
143         movl    4(%esp), %eax
144         movl    $1000, %edx
145         mul     %edx            /* Milli seconds to nano seconds.  */
146         movl    (%edi), %ecx
147         movl    4(%edi), %edx
148         subl    (%esp), %ecx
149         subl    %eax, %edx
150         jns     4f
151         addl    $1000000000, %edx
152         subl    $1, %ecx
153 4:      testl   %ecx, %ecx
154         js      8f              /* Time is already up.  */
156         /* Store relative timeout.  */
157         movl    %ecx, (%esp)
158         movl    %edx, 4(%esp)
160         movl    %ebp, %ebx
162         movl    8(%esp), %edx
163         movl    %edx, %eax
164         orl     $FUTEX_WAITERS, %edx
166         testl   $FUTEX_OWNER_DIED, %eax
167         jnz     6f
169         cmpl    %eax, %edx
170         je      2f
172         LOCK
173         cmpxchgl %edx, (%ebx)
174         movl    $0, %ecx        /* Must use mov to avoid changing cc.  */
175         jnz     5f
178         /* Futex call.  */
179         movl    %esp, %esi
180         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
181         movl    $SYS_futex, %eax
182         ENTER_KERNEL
183         movl    %eax, %ecx
185         movl    (%ebx), %eax
187 5:      testl   %eax, %eax
188         jne     7f
190         movl    %gs:TID, %edx
191         orl     $FUTEX_WAITERS, %edx
192         LOCK
193         cmpxchgl %edx, (%ebx)
194         jnz     7f
196 6:      addl    $12, %esp
197         cfi_adjust_cfa_offset(-12)
198         popl    %ebp
199         cfi_adjust_cfa_offset(-4)
200         cfi_restore(%ebp)
201         popl    %ebx
202         cfi_adjust_cfa_offset(-4)
203         cfi_restore(%ebx)
204         popl    %esi
205         cfi_adjust_cfa_offset(-4)
206         cfi_restore(%esi)
207         popl    %edi
208         cfi_adjust_cfa_offset(-4)
209         cfi_restore(%edi)
210         ret
212 3:      movl    $EINVAL, %eax
213         ret
215         cfi_adjust_cfa_offset(28)
216         cfi_offset(%edi, -8)
217         cfi_offset(%esi, -12)
218         cfi_offset(%ebx, -16)
219         cfi_offset(%ebp, -20)
220         /* Check whether the time expired.  */
221 7:      cmpl    $-ETIMEDOUT, %ecx
222         jne     1b
224 8:      movl    $ETIMEDOUT, %eax
225         jmp     6b
226         cfi_endproc
227         .size   __lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait