]>
Commit | Line | Data |
---|---|---|
2f42e8be | 1 | /* Copyright (C) 2002, 2003 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 | |
35 | #define FUTEX_WAIT 0 | |
36 | #define FUTEX_WAKE 1 | |
37 | ||
76a50749 | 38 | |
71451de2 UD |
39 | .globl __lll_mutex_lock_wait |
40 | .type __lll_mutex_lock_wait,@function | |
41 | .hidden __lll_mutex_lock_wait | |
76a50749 | 42 | .align 16 |
71451de2 | 43 | __lll_mutex_lock_wait: |
76a50749 UD |
44 | pushl %esi |
45 | pushl %ebx | |
46 | pushl %edx | |
47 | ||
48 | movl %ecx, %ebx | |
49 | xorl %esi, %esi /* No timeout. */ | |
50 | xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ | |
71451de2 UD |
51 | movl $2, %edx |
52 | ||
76a50749 | 53 | 1: |
71451de2 UD |
54 | movl $1, %eax |
55 | LOCK | |
56 | cmpxchgl %edx, (%ebx) | |
57 | ||
58 | testl %eax, %eax | |
59 | je 2f | |
60 | ||
76a50749 | 61 | movl $SYS_futex, %eax |
097eca29 | 62 | ENTER_KERNEL |
76a50749 | 63 | |
71451de2 UD |
64 | xorl %eax, %eax |
65 | 2: LOCK | |
66 | cmpxchgl %edx, (%ebx) | |
76a50749 | 67 | |
3a226d33 | 68 | jnz,pn 1b |
76a50749 UD |
69 | |
70 | popl %edx | |
71 | popl %ebx | |
72 | popl %esi | |
73 | ret | |
71451de2 UD |
74 | .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait |
75 | ||
76 | ||
77 | #ifdef NOT_IN_libc | |
78 | .globl __lll_mutex_timedlock_wait | |
79 | .type __lll_mutex_timedlock_wait,@function | |
80 | .hidden __lll_mutex_timedlock_wait | |
81 | .align 16 | |
82 | __lll_mutex_timedlock_wait: | |
83 | /* Check for a valid timeout value. */ | |
84 | cmpl $1000000000, 4(%edx) | |
85 | jae 3f | |
86 | ||
87 | pushl %edi | |
88 | pushl %esi | |
89 | pushl %ebx | |
90 | pushl %ebp | |
91 | ||
92 | /* Stack frame for the timespec and timeval structs. */ | |
93 | subl $8, %esp | |
94 | ||
95 | movl %ecx, %ebp | |
96 | movl %edx, %edi | |
97 | ||
98 | 1: | |
99 | /* Get current time. */ | |
100 | movl %esp, %ebx | |
101 | xorl %ecx, %ecx | |
102 | movl $SYS_gettimeofday, %eax | |
103 | ENTER_KERNEL | |
104 | ||
105 | /* Compute relative timeout. */ | |
106 | movl 4(%esp), %eax | |
107 | movl $1000, %edx | |
108 | mul %edx /* Milli seconds to nano seconds. */ | |
109 | movl (%edi), %ecx | |
110 | movl 4(%edi), %edx | |
111 | subl (%esp), %ecx | |
112 | subl %eax, %edx | |
113 | jns 4f | |
114 | addl $1000000000, %edx | |
115 | subl $1, %ecx | |
116 | 4: testl %ecx, %ecx | |
117 | js 5f /* Time is already up. */ | |
118 | ||
119 | /* Store relative timeout. */ | |
120 | movl %ecx, (%esp) | |
121 | movl %edx, 4(%esp) | |
122 | ||
123 | movl %ebp, %ebx | |
124 | ||
125 | movl $1, %eax | |
126 | movl $2, %edx | |
127 | LOCK | |
128 | cmpxchgl %edx, (%ebx) | |
129 | ||
130 | testl %eax, %eax | |
131 | je 8f | |
132 | ||
133 | /* Futex call. */ | |
134 | movl %esp, %esi | |
135 | xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ | |
136 | movl $SYS_futex, %eax | |
137 | ENTER_KERNEL | |
138 | movl %eax, %ecx | |
139 | ||
140 | 8: | |
141 | xorl %eax, %eax | |
142 | movl $2, %edx | |
143 | LOCK | |
144 | cmpxchgl %edx, (%ebx) | |
145 | ||
3a226d33 | 146 | jnz 7f |
71451de2 UD |
147 | |
148 | 6: addl $8, %esp | |
149 | popl %ebp | |
150 | popl %ebx | |
151 | popl %esi | |
152 | popl %edi | |
153 | ret | |
154 | ||
155 | /* Check whether the time expired. */ | |
156 | 7: cmpl $-ETIMEDOUT, %ecx | |
157 | je 5f | |
158 | jmp 1b | |
159 | ||
160 | 3: movl $EINVAL, %eax | |
161 | ret | |
162 | ||
163 | 5: movl $ETIMEDOUT, %eax | |
164 | jmp 6b | |
165 | .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait | |
166 | #endif | |
76a50749 UD |
167 | |
168 | ||
9356d063 | 169 | #ifdef NOT_IN_libc |
76a50749 UD |
170 | .globl lll_unlock_wake_cb |
171 | .type lll_unlock_wake_cb,@function | |
172 | .hidden lll_unlock_wake_cb | |
173 | .align 16 | |
174 | lll_unlock_wake_cb: | |
76a50749 UD |
175 | pushl %ebx |
176 | pushl %ecx | |
177 | pushl %edx | |
178 | ||
179 | movl 20(%esp), %ebx | |
180 | LOCK | |
71451de2 UD |
181 | subl $1, (%ebx) |
182 | je 1f | |
76a50749 | 183 | |
71451de2 UD |
184 | movl $FUTEX_WAKE, %ecx |
185 | movl $1, %edx /* Wake one thread. */ | |
186 | movl $SYS_futex, %eax | |
187 | movl $0, (%ebx) | |
188 | ENTER_KERNEL | |
189 | ||
190 | 1: popl %edx | |
76a50749 UD |
191 | popl %ecx |
192 | popl %ebx | |
76a50749 UD |
193 | ret |
194 | .size lll_unlock_wake_cb,.-lll_unlock_wake_cb | |
9356d063 | 195 | #endif |
76a50749 UD |
196 | |
197 | ||
71451de2 UD |
198 | .globl __lll_mutex_unlock_wake |
199 | .type __lll_mutex_unlock_wake,@function | |
200 | .hidden __lll_mutex_unlock_wake | |
bd8bb78b | 201 | .align 16 |
71451de2 | 202 | __lll_mutex_unlock_wake: |
76a50749 UD |
203 | pushl %ebx |
204 | pushl %ecx | |
205 | pushl %edx | |
206 | ||
207 | movl %eax, %ebx | |
71451de2 UD |
208 | movl $0, (%eax) |
209 | movl $FUTEX_WAKE, %ecx | |
76a50749 | 210 | movl $1, %edx /* Wake one thread. */ |
76a50749 | 211 | movl $SYS_futex, %eax |
097eca29 | 212 | ENTER_KERNEL |
76a50749 UD |
213 | |
214 | popl %edx | |
215 | popl %ecx | |
216 | popl %ebx | |
76a50749 | 217 | ret |
71451de2 | 218 | .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake |
76a50749 UD |
219 | |
220 | ||
9356d063 | 221 | #ifdef NOT_IN_libc |
76a50749 UD |
222 | .globl __lll_timedwait_tid |
223 | .type __lll_timedwait_tid,@function | |
224 | .hidden __lll_timedwait_tid | |
bd8bb78b | 225 | .align 16 |
76a50749 UD |
226 | __lll_timedwait_tid: |
227 | pushl %edi | |
228 | pushl %esi | |
229 | pushl %ebx | |
230 | pushl %ebp | |
231 | ||
232 | movl %eax, %ebp | |
233 | movl %edx, %edi | |
234 | subl $8, %esp | |
235 | ||
236 | /* Get current time. */ | |
237 | 2: movl %esp, %ebx | |
238 | xorl %ecx, %ecx | |
239 | movl $SYS_gettimeofday, %eax | |
097eca29 | 240 | ENTER_KERNEL |
76a50749 UD |
241 | |
242 | /* Compute relative timeout. */ | |
243 | movl 4(%esp), %eax | |
244 | movl $1000, %edx | |
245 | mul %edx /* Milli seconds to nano seconds. */ | |
246 | movl (%edi), %ecx | |
247 | movl 4(%edi), %edx | |
248 | subl (%esp), %ecx | |
249 | subl %eax, %edx | |
250 | jns 5f | |
251 | addl $1000000000, %edx | |
ccf1d573 | 252 | subl $1, %ecx |
76a50749 UD |
253 | 5: testl %ecx, %ecx |
254 | js 6f /* Time is already up. */ | |
255 | ||
256 | movl %ecx, (%esp) /* Store relative timeout. */ | |
257 | movl %edx, 4(%esp) | |
258 | ||
259 | movl (%ebp), %edx | |
260 | testl %edx, %edx | |
261 | jz 4f | |
262 | ||
263 | movl %esp, %esi | |
264 | xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ | |
265 | movl %ebp, %ebx | |
266 | movl $SYS_futex, %eax | |
097eca29 | 267 | ENTER_KERNEL |
76a50749 | 268 | |
76a50749 UD |
269 | cmpl $0, (%ebx) |
270 | jne 1f | |
271 | 4: xorl %eax, %eax | |
272 | ||
273 | 3: addl $8, %esp | |
274 | popl %ebp | |
275 | popl %ebx | |
276 | popl %esi | |
277 | popl %edi | |
278 | ret | |
279 | ||
3273832c | 280 | 1: cmpl $-ETIMEDOUT, %eax |
76a50749 UD |
281 | jne 2b |
282 | 6: movl $ETIMEDOUT, %eax | |
283 | jmp 3b | |
284 | .size __lll_timedwait_tid,.-__lll_timedwait_tid | |
9356d063 | 285 | #endif |