]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S
* stdlib/tst-strtod2.c (do_test): Use %tu in fmt string for ptrdiff_t
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevellock.S
CommitLineData
5a8075b1 1/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
76a50749
UD
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>
326132db 21#include <pthread-errnos.h>
76a50749
UD
22
23 .text
24
9356d063
UD
25#ifndef LOCK
26# ifdef UP
27# define LOCK
28# else
29# define LOCK lock
30# endif
76a50749
UD
31#endif
32
33#define SYS_gettimeofday __NR_gettimeofday
34#define SYS_futex 240
5a8075b1
UD
35#ifndef FUTEX_WAIT
36# define FUTEX_WAIT 0
37# define FUTEX_WAKE 1
38#endif
39
40#ifndef LOAD_FUTEX_WAIT
41# if FUTEX_WAIT == 0
42# define LOAD_FUTEX_WAIT(reg) \
43 xorl reg, reg
44# else
45# define LOAD_FUTEX_WAIT(reg) \
46 movl $FUTEX_WAIT, reg
47# endif
48# define LOAD_FUTEX_WAKE(reg) \
49 movl $FUTEX_WAKE, reg
50#endif
76a50749 51
76a50749 52
71451de2
UD
53 .globl __lll_mutex_lock_wait
54 .type __lll_mutex_lock_wait,@function
55 .hidden __lll_mutex_lock_wait
76a50749 56 .align 16
71451de2 57__lll_mutex_lock_wait:
cd248c3f 58 cfi_startproc
76a50749 59 pushl %edx
cd248c3f 60 cfi_adjust_cfa_offset(4)
c0df57e1 61 pushl %ebx
cd248c3f 62 cfi_adjust_cfa_offset(4)
c0df57e1 63 pushl %esi
cd248c3f
UD
64 cfi_adjust_cfa_offset(4)
65 cfi_offset(%edx, -8)
66 cfi_offset(%ebx, -12)
67 cfi_offset(%esi, -16)
76a50749 68
c0df57e1 69 movl $2, %edx
76a50749
UD
70 movl %ecx, %ebx
71 xorl %esi, %esi /* No timeout. */
5a8075b1 72 LOAD_FUTEX_WAIT (%ecx)
71451de2 73
a8fd5a02 74 cmpl %edx, %eax /* NB: %edx == 2 */
ebddb424 75 jne 2f
71451de2 76
a8fd5a02 771: movl $SYS_futex, %eax
097eca29 78 ENTER_KERNEL
76a50749 79
ebddb424 802: movl %edx, %eax
a8fd5a02 81 xchgl %eax, (%ebx) /* NB: lock is implied */
76a50749 82
a8fd5a02 83 testl %eax, %eax
ab9a9ff8 84 jnz 1b
76a50749 85
ebddb424 86 popl %esi
cd248c3f
UD
87 cfi_adjust_cfa_offset(-4)
88 cfi_restore(%esi)
c0df57e1 89 popl %ebx
cd248c3f
UD
90 cfi_adjust_cfa_offset(-4)
91 cfi_restore(%ebx)
c0df57e1 92 popl %edx
cd248c3f
UD
93 cfi_adjust_cfa_offset(-4)
94 cfi_restore(%edx)
76a50749 95 ret
cd248c3f 96 cfi_endproc
71451de2
UD
97 .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
98
99
100#ifdef NOT_IN_libc
101 .globl __lll_mutex_timedlock_wait
102 .type __lll_mutex_timedlock_wait,@function
103 .hidden __lll_mutex_timedlock_wait
104 .align 16
105__lll_mutex_timedlock_wait:
cd248c3f 106 cfi_startproc
71451de2
UD
107 /* Check for a valid timeout value. */
108 cmpl $1000000000, 4(%edx)
109 jae 3f
110
111 pushl %edi
cd248c3f 112 cfi_adjust_cfa_offset(4)
71451de2 113 pushl %esi
cd248c3f 114 cfi_adjust_cfa_offset(4)
71451de2 115 pushl %ebx
cd248c3f 116 cfi_adjust_cfa_offset(4)
71451de2 117 pushl %ebp
cd248c3f
UD
118 cfi_adjust_cfa_offset(4)
119 cfi_offset(%edi, -8)
120 cfi_offset(%esi, -12)
121 cfi_offset(%ebx, -16)
122 cfi_offset(%ebp, -20)
71451de2
UD
123
124 /* Stack frame for the timespec and timeval structs. */
125 subl $8, %esp
cd248c3f 126 cfi_adjust_cfa_offset(8)
71451de2
UD
127
128 movl %ecx, %ebp
129 movl %edx, %edi
130
1311:
132 /* Get current time. */
133 movl %esp, %ebx
134 xorl %ecx, %ecx
135 movl $SYS_gettimeofday, %eax
136 ENTER_KERNEL
137
138 /* Compute relative timeout. */
139 movl 4(%esp), %eax
140 movl $1000, %edx
141 mul %edx /* Milli seconds to nano seconds. */
142 movl (%edi), %ecx
143 movl 4(%edi), %edx
144 subl (%esp), %ecx
145 subl %eax, %edx
146 jns 4f
147 addl $1000000000, %edx
148 subl $1, %ecx
1494: testl %ecx, %ecx
150 js 5f /* Time is already up. */
151
152 /* Store relative timeout. */
153 movl %ecx, (%esp)
154 movl %edx, 4(%esp)
155
156 movl %ebp, %ebx
157
158 movl $1, %eax
159 movl $2, %edx
160 LOCK
161 cmpxchgl %edx, (%ebx)
162
163 testl %eax, %eax
164 je 8f
165
166 /* Futex call. */
167 movl %esp, %esi
5a8075b1 168 LOAD_FUTEX_WAIT (%ecx)
71451de2
UD
169 movl $SYS_futex, %eax
170 ENTER_KERNEL
171 movl %eax, %ecx
172
c1b48791 1738: /* NB: %edx == 2 */
71451de2 174 xorl %eax, %eax
71451de2
UD
175 LOCK
176 cmpxchgl %edx, (%ebx)
177
3a226d33 178 jnz 7f
71451de2
UD
179
1806: addl $8, %esp
cd248c3f 181 cfi_adjust_cfa_offset(-8)
71451de2 182 popl %ebp
cd248c3f
UD
183 cfi_adjust_cfa_offset(-4)
184 cfi_restore(%ebp)
71451de2 185 popl %ebx
cd248c3f
UD
186 cfi_adjust_cfa_offset(-4)
187 cfi_restore(%ebx)
71451de2 188 popl %esi
cd248c3f
UD
189 cfi_adjust_cfa_offset(-4)
190 cfi_restore(%esi)
71451de2 191 popl %edi
cd248c3f
UD
192 cfi_adjust_cfa_offset(-4)
193 cfi_restore(%edi)
71451de2
UD
194 ret
195
cd248c3f
UD
1963: movl $EINVAL, %eax
197 ret
198
199 cfi_adjust_cfa_offset(24)
200 cfi_offset(%edi, -8)
201 cfi_offset(%esi, -12)
202 cfi_offset(%ebx, -16)
203 cfi_offset(%ebp, -20)
71451de2
UD
204 /* Check whether the time expired. */
2057: cmpl $-ETIMEDOUT, %ecx
206 je 5f
c1b48791
UD
207
208 /* Make sure the current holder knows we are going to sleep. */
209 movl %edx, %eax
210 xchgl %eax, (%ebx)
211 testl %eax, %eax
212 jz 6b
71451de2
UD
213 jmp 1b
214
71451de2
UD
2155: movl $ETIMEDOUT, %eax
216 jmp 6b
cd248c3f 217 cfi_endproc
71451de2
UD
218 .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
219#endif
76a50749
UD
220
221
71451de2
UD
222 .globl __lll_mutex_unlock_wake
223 .type __lll_mutex_unlock_wake,@function
224 .hidden __lll_mutex_unlock_wake
bd8bb78b 225 .align 16
71451de2 226__lll_mutex_unlock_wake:
cd248c3f 227 cfi_startproc
76a50749 228 pushl %ebx
cd248c3f 229 cfi_adjust_cfa_offset(4)
76a50749 230 pushl %ecx
cd248c3f 231 cfi_adjust_cfa_offset(4)
76a50749 232 pushl %edx
cd248c3f
UD
233 cfi_adjust_cfa_offset(4)
234 cfi_offset(%ebx, -8)
235 cfi_offset(%ecx, -12)
236 cfi_offset(%edx, -16)
76a50749
UD
237
238 movl %eax, %ebx
71451de2 239 movl $0, (%eax)
5a8075b1 240 LOAD_FUTEX_WAKE (%ecx)
76a50749 241 movl $1, %edx /* Wake one thread. */
76a50749 242 movl $SYS_futex, %eax
097eca29 243 ENTER_KERNEL
76a50749
UD
244
245 popl %edx
cd248c3f
UD
246 cfi_adjust_cfa_offset(-4)
247 cfi_restore(%edx)
76a50749 248 popl %ecx
cd248c3f
UD
249 cfi_adjust_cfa_offset(-4)
250 cfi_restore(%ecx)
76a50749 251 popl %ebx
cd248c3f
UD
252 cfi_adjust_cfa_offset(-4)
253 cfi_restore(%ebx)
76a50749 254 ret
cd248c3f 255 cfi_endproc
71451de2 256 .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
76a50749
UD
257
258
9356d063 259#ifdef NOT_IN_libc
76a50749
UD
260 .globl __lll_timedwait_tid
261 .type __lll_timedwait_tid,@function
262 .hidden __lll_timedwait_tid
bd8bb78b 263 .align 16
76a50749
UD
264__lll_timedwait_tid:
265 pushl %edi
266 pushl %esi
267 pushl %ebx
268 pushl %ebp
269
270 movl %eax, %ebp
271 movl %edx, %edi
272 subl $8, %esp
273
274 /* Get current time. */
2752: movl %esp, %ebx
276 xorl %ecx, %ecx
277 movl $SYS_gettimeofday, %eax
097eca29 278 ENTER_KERNEL
76a50749
UD
279
280 /* Compute relative timeout. */
281 movl 4(%esp), %eax
282 movl $1000, %edx
283 mul %edx /* Milli seconds to nano seconds. */
284 movl (%edi), %ecx
285 movl 4(%edi), %edx
286 subl (%esp), %ecx
287 subl %eax, %edx
288 jns 5f
289 addl $1000000000, %edx
ccf1d573 290 subl $1, %ecx
76a50749
UD
2915: testl %ecx, %ecx
292 js 6f /* Time is already up. */
293
294 movl %ecx, (%esp) /* Store relative timeout. */
295 movl %edx, 4(%esp)
296
297 movl (%ebp), %edx
298 testl %edx, %edx
299 jz 4f
300
301 movl %esp, %esi
5a8075b1
UD
302 /* XXX The kernel so far uses global futex for the wakeup at
303 all times. */
76a50749
UD
304 xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
305 movl %ebp, %ebx
306 movl $SYS_futex, %eax
097eca29 307 ENTER_KERNEL
76a50749 308
76a50749
UD
309 cmpl $0, (%ebx)
310 jne 1f
3114: xorl %eax, %eax
312
3133: addl $8, %esp
314 popl %ebp
315 popl %ebx
316 popl %esi
317 popl %edi
318 ret
319
3273832c 3201: cmpl $-ETIMEDOUT, %eax
76a50749
UD
321 jne 2b
3226: movl $ETIMEDOUT, %eax
323 jmp 3b
324 .size __lll_timedwait_tid,.-__lll_timedwait_tid
9356d063 325#endif