]>
Commit | Line | Data |
---|---|---|
76a50749 UD |
1 | /* Copyright (C) 2002 Free Software Foundation, Inc. |
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> | |
21 | #include <shlib-compat.h> | |
22 | ||
23 | .text | |
24 | ||
25 | #ifndef UP | |
26 | # define LOCK lock | |
27 | #else | |
28 | # define | |
29 | #endif | |
30 | ||
31 | #define SYS_gettimeofday __NR_gettimeofday | |
32 | #define SYS_futex 240 | |
33 | #define FUTEX_WAKE 1 | |
34 | ||
35 | #define EINTR 4 | |
36 | #define EAGAIN 11 | |
37 | #define EWOULDBLOCK EAGAIN | |
38 | #define EINVAL 22 | |
39 | #define ETIMEDOUT 110 | |
40 | ||
41 | ||
42 | .globl __new_sem_wait | |
43 | .type __new_sem_wait,@function | |
44 | .align 16 | |
45 | __new_sem_wait: | |
46 | pushl %ebx | |
47 | pushl %esi | |
48 | ||
49 | movl 12(%esp), %ebx | |
50 | ||
51 | 3: movl (%ebx), %eax | |
52 | 2: testl %eax, %eax | |
53 | je,pn 1f | |
54 | ||
55 | leal -1(%eax), %edx | |
56 | LOCK | |
57 | cmpxchgl %edx, (%ebx) | |
58 | jne,pn 2b | |
59 | xorl %eax, %eax | |
60 | ||
61 | popl %esi | |
62 | popl %ebx | |
63 | ret | |
64 | ||
65 | 1: xorl %esi, %esi | |
66 | movl $SYS_futex, %eax | |
67 | movl %esi, %ecx | |
68 | movl %esi, %edx | |
097eca29 | 69 | ENTER_KERNEL |
76a50749 UD |
70 | |
71 | testl %eax, %eax | |
72 | je 3b | |
73 | cmpl $-EWOULDBLOCK, %eax | |
74 | je 3b | |
75 | negl %eax | |
76 | #ifdef PIC | |
77 | call __i686.get_pc_thunk.bx | |
78 | #else | |
79 | movl $4f, %ebx | |
80 | 4: | |
81 | #endif | |
82 | addl $_GLOBAL_OFFSET_TABLE_, %ebx | |
83 | movl %gs:0, %edx | |
84 | subl errno@gottpoff(%ebx), %edx | |
85 | movl %eax, (%edx) | |
86 | orl $-1, %eax | |
87 | popl %esi | |
88 | popl %ebx | |
89 | ret | |
90 | .size __new_sem_wait,.-__new_sem_wait | |
91 | .symver __new_sem_wait, sem_wait@@GLIBC_2.1 | |
92 | #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) | |
93 | .global __old_sem_wait | |
94 | __old_sem_wait = __new_sem_wait | |
95 | .symver __old_sem_wait, sem_wait@GLIBC_2.0 | |
96 | #endif | |
97 | ||
98 | ||
99 | .globl __new_sem_trywait | |
100 | .type __new_sem_trywait,@function | |
101 | .align 16 | |
102 | __new_sem_trywait: | |
103 | movl 4(%esp), %ecx | |
104 | ||
105 | movl (%ecx), %eax | |
106 | 2: testl %eax, %eax | |
107 | jz 1f | |
108 | ||
109 | leal -1(%eax), %edx | |
110 | LOCK | |
111 | cmpxchgl %edx, (%ecx) | |
112 | jne,pn 2b | |
113 | xorl %eax, %eax | |
114 | ret | |
115 | ||
116 | 1: | |
117 | #ifdef PIC | |
118 | call __i686.get_pc_thunk.cx | |
119 | #else | |
120 | movl $3f, %ecx | |
121 | 3: | |
122 | #endif | |
123 | addl $_GLOBAL_OFFSET_TABLE_, %ecx | |
124 | movl %gs:0, %edx | |
125 | subl errno@gottpoff(%ecx), %edx | |
126 | movl $EAGAIN, (%edx) | |
127 | orl $-1, %eax | |
128 | ret | |
129 | .size __new_sem_trywait,.-__new_sem_trywait | |
130 | .symver __new_sem_trywait, sem_trywait@@GLIBC_2.1 | |
131 | #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) | |
132 | .global __old_sem_trywait | |
133 | __old_sem_trywait = __new_sem_trywait | |
134 | .symver __old_sem_trywait, sem_trywait@GLIBC_2.0 | |
135 | #endif | |
136 | ||
137 | ||
138 | .globl sem_timedwait | |
139 | .type sem_timedwait,@function | |
140 | .align 16 | |
141 | sem_timedwait: | |
142 | movl 4(%esp), %ecx | |
143 | ||
144 | movl (%ecx), %eax | |
145 | 2: testl %eax, %eax | |
146 | je,pn 1f | |
147 | ||
148 | leal -1(%eax), %edx | |
149 | LOCK | |
150 | cmpxchgl %edx, (%ecx) | |
151 | jne,pn 2b | |
152 | ||
153 | xorl %eax, %eax | |
154 | ret | |
155 | ||
156 | /* Check whether the timeout value is valid. */ | |
157 | 1: pushl %esi | |
158 | pushl %edi | |
159 | pushl %ebx | |
160 | subl $8, %esp | |
161 | ||
162 | movl %esp, %esi | |
163 | movl 28(%esp), %edi | |
164 | ||
165 | /* Check for invalid nanosecond field. */ | |
166 | cmpl $1000000000, 4(%edi) | |
167 | movl $EINVAL, %eax | |
168 | jae 6f | |
169 | ||
170 | 7: xorl %ecx, %ecx | |
171 | movl %esp, %ebx | |
172 | movl %ecx, %edx | |
173 | movl $SYS_gettimeofday, %eax | |
097eca29 | 174 | ENTER_KERNEL |
76a50749 UD |
175 | |
176 | /* Compute relative timeout. */ | |
177 | movl 4(%esp), %eax | |
178 | movl $1000, %edx | |
179 | mul %edx /* Milli seconds to nano seconds. */ | |
180 | movl (%edi), %ecx | |
181 | movl 4(%edi), %edx | |
182 | subl (%esp), %ecx | |
183 | subl %eax, %edx | |
184 | jns 5f | |
185 | addl $1000000000, %edx | |
186 | decl %ecx | |
187 | 5: testl %ecx, %ecx | |
188 | movl $ETIMEDOUT, %eax | |
189 | js 6f /* Time is already up. */ | |
190 | ||
191 | movl %ecx, (%esp) /* Store relative timeout. */ | |
192 | movl %edx, 4(%esp) | |
193 | movl 24(%esp), %ebx | |
194 | xorl %ecx, %ecx | |
195 | movl $SYS_futex, %eax | |
196 | xorl %edx, %edx | |
097eca29 | 197 | ENTER_KERNEL |
76a50749 UD |
198 | |
199 | testl %eax, %eax | |
200 | je,pt 9f | |
201 | cmpl $-EWOULDBLOCK, %eax | |
202 | jne 3f | |
203 | ||
204 | 9: movl (%ebx), %eax | |
205 | 8: testl %eax, %eax | |
206 | je 7b | |
207 | ||
208 | leal -1(%eax), %ecx | |
209 | LOCK | |
210 | cmpxchgl %ecx, (%ebx) | |
211 | jne,pn 8b | |
212 | ||
213 | addl $8, %esp | |
214 | xorl %eax, %eax | |
215 | popl %ebx | |
216 | popl %edi | |
217 | popl %esi | |
218 | ret | |
219 | ||
220 | 3: negl %eax | |
221 | 6: | |
222 | #ifdef PIC | |
223 | call __i686.get_pc_thunk.bx | |
224 | #else | |
225 | movl $4f, %ebx | |
226 | 4: | |
227 | #endif | |
228 | addl $_GLOBAL_OFFSET_TABLE_, %ebx | |
229 | movl %gs:0, %edx | |
230 | subl errno@gottpoff(%ebx), %edx | |
231 | movl %eax, (%edx) | |
232 | ||
233 | addl $8, %esp | |
234 | orl $-1, %eax | |
235 | popl %ebx | |
236 | popl %edi | |
237 | popl %esi | |
238 | ret | |
239 | .size sem_timedwait,.-sem_timedwait | |
240 | ||
241 | ||
242 | .globl __new_sem_post | |
243 | .type __new_sem_post,@function | |
244 | .align 16 | |
245 | __new_sem_post: | |
246 | pushl %esi | |
247 | pushl %ebx | |
248 | ||
249 | movl 12(%esp), %ebx | |
250 | movl $1, %edx | |
251 | LOCK | |
252 | xaddl %edx, (%ebx) | |
253 | ||
254 | xorl %esi, %esi | |
255 | movl $SYS_futex, %eax | |
256 | movl $FUTEX_WAKE, %ecx | |
257 | incl %edx | |
097eca29 | 258 | ENTER_KERNEL |
76a50749 UD |
259 | |
260 | testl %eax, %eax | |
261 | js 1f | |
262 | ||
263 | popl %ebx | |
264 | popl %esi | |
265 | ret | |
266 | ||
267 | 1: | |
268 | #ifdef PIC | |
269 | call __i686.get_pc_thunk.bx | |
270 | #else | |
271 | movl $4f, %ebx | |
272 | 4: | |
273 | #endif | |
274 | addl $_GLOBAL_OFFSET_TABLE_, %ebx | |
275 | movl %gs:0, %edx | |
276 | subl errno@gottpoff(%ebx), %edx | |
277 | movl $EINVAL, (%edx) | |
278 | ||
279 | orl $-1, %eax | |
280 | popl %ebx | |
281 | popl %esi | |
282 | ret | |
283 | .size __new_sem_post,.-__new_sem_post | |
284 | .symver __new_sem_post, sem_post@@GLIBC_2.1 | |
285 | #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) | |
286 | .global __old_sem_post | |
287 | __old_sem_post = __new_sem_post | |
288 | .symver __old_sem_post, sem_post@GLIBC_2.0 | |
289 | #endif | |
290 | ||
291 | ||
292 | #ifdef PIC | |
293 | .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits | |
294 | .globl __i686.get_pc_thunk.bx | |
295 | .hidden __i686.get_pc_thunk.bx | |
296 | .type __i686.get_pc_thunk.bx,@function | |
297 | __i686.get_pc_thunk.bx: | |
298 | movl (%esp), %ebx; | |
299 | ret | |
300 | .size __i686.get_pc_thunk.bx,.-__i686.get_pc_thunk.bx | |
301 | ||
302 | ||
303 | .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits | |
304 | .globl __i686.get_pc_thunk.cx | |
305 | .hidden __i686.get_pc_thunk.cx | |
306 | .type __i686.get_pc_thunk.cx,@function | |
307 | __i686.get_pc_thunk.cx: | |
308 | movl (%esp), %ecx; | |
309 | ret | |
310 | .size __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx | |
311 | #endif |