Unconditionally include <dl-sysdep.h>.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevelsem.S
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
69         int     $0x80
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
174         int     $0x80
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
197         int     $0x80
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
258         int     $0x80
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