]>
Commit | Line | Data |
---|---|---|
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 | 77 | 1: movl $SYS_futex, %eax |
097eca29 | 78 | ENTER_KERNEL |
76a50749 | 79 | |
ebddb424 | 80 | 2: 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 | ||
131 | 1: | |
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 | |
149 | 4: 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 | 173 | 8: /* NB: %edx == 2 */ |
71451de2 | 174 | xorl %eax, %eax |
71451de2 UD |
175 | LOCK |
176 | cmpxchgl %edx, (%ebx) | |
177 | ||
3a226d33 | 178 | jnz 7f |
71451de2 UD |
179 | |
180 | 6: 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 |
196 | 3: 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. */ |
205 | 7: 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 |
215 | 5: 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. */ | |
275 | 2: 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 |
291 | 5: 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 | |
311 | 4: xorl %eax, %eax | |
312 | ||
313 | 3: addl $8, %esp | |
314 | popl %ebp | |
315 | popl %ebx | |
316 | popl %esi | |
317 | popl %edi | |
318 | ret | |
319 | ||
3273832c | 320 | 1: cmpl $-ETIMEDOUT, %eax |
76a50749 UD |
321 | jne 2b |
322 | 6: movl $ETIMEDOUT, %eax | |
323 | jmp 3b | |
324 | .size __lll_timedwait_tid,.-__lll_timedwait_tid | |
9356d063 | 325 | #endif |