Use ENTER_KERNEL instead of int $0x80.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / lowlevelcond.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
22         .text
23
24 #ifdef UP
25 # define LOCK
26 #else
27 # define LOCK lock
28 #endif
29
30 #define SYS_gettimeofday        __NR_gettimeofday
31 #define SYS_futex               240
32 #define FUTEX_WAIT              0
33 #define FUTEX_WAKE              1
34
35 #define EWOULDBLOCK             11
36 #define EINVAL                  22
37 #define ETIMEDOUT               110
38
39 #define cond_lock        0
40 #define cond_nr_wakers   4
41 #define cond_nr_sleepers 8
42
43
44         .global __lll_cond_wait
45         .type   __lll_cond_wait,@function
46         .hidden __lll_cond_wait
47         .align  16
48 __lll_cond_wait:
49         pushl   %esi
50         pushl   %ebx
51
52         xorl    %esi, %esi
53
54         leal    cond_nr_wakers(%eax), %ebx
55
56 4:      movl    (%ebx), %edx
57         testl   %edx, %edx
58         jne     1f
59
60         LOCK
61         decl    cond_lock-cond_nr_wakers(%ebx)
62         jne     2f
63
64 3:      xorl    %ecx, %ecx
65         movl    $SYS_futex, %eax
66         ENTER_KERNEL
67
68         movl    $1, %eax
69         LOCK
70         xaddl   %eax, cond_lock-cond_nr_wakers(%ebx)
71         testl   %eax, %eax
72         je      4b
73
74         leal    cond_lock-cond_nr_wakers(%ebx), %ecx
75         /* Preserves %ebx, %edx, %edi, %esi.  */
76         call    __lll_mutex_lock_wait
77         jmp     4b
78
79 1:      decl    (%ebx)
80
81         popl    %ebx
82         popl    %esi
83         ret
84
85 2:      leal    cond_lock-cond_nr_wakers(%ebx), %eax
86         /* Preserves %ebx, %ecx, %edx, %edi, %esi.  */
87         call    __lll_mutex_unlock_wake
88         jmp     3b
89         .size   __lll_cond_wait,.-__lll_cond_wait
90
91
92         .global __lll_cond_timedwait
93         .type   __lll_cond_timedwait,@function
94         .hidden __lll_cond_timedwait
95         .align  16
96 __lll_cond_timedwait:
97         /* Check for a valid timeout value.  */
98         cmpl    $1000000000, 4(%edx)
99         jae     1f
100
101         pushl   %ebp
102         pushl   %edi
103         pushl   %esi
104         pushl   %ebx
105
106         /* Stack frame for the timespec and timeval structs.  */
107         subl    $8, %esp
108
109         leal    cond_nr_wakers(%eax), %ebp      /* cond */
110         movl    %edx, %edi                      /* timeout */
111
112 9:      movl    (%ebp), %esi
113         testl   %esi, %esi
114         jne     5f
115
116         LOCK
117         decl    cond_lock-cond_nr_wakers(%ebp)
118         jne     6f
119
120         /* Get current time.  */
121 7:      movl    %esp, %ebx
122         xorl    %ecx, %ecx
123         movl    $SYS_gettimeofday, %eax
124         ENTER_KERNEL
125
126         /* Compute relative timeout.  */
127         movl    4(%esp), %eax
128         movl    $1000, %edx
129         mul     %edx            /* Milli seconds to nano seconds.  */
130         movl    (%edi), %ecx
131         movl    4(%edi), %edx
132         subl    (%esp), %ecx
133         subl    %eax, %edx
134         jns     3f
135         addl    $1000000000, %edx
136         decl    %ecx
137 3:      testl   %ecx, %ecx
138         js      4f              /* Time is already up.  */
139
140         movl    %ecx, (%esp)    /* Store relative timeout.  */
141         movl    %edx, 4(%esp)
142         movl    %esi, %edx
143         movl    %esp, %esi
144         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
145         movl    %ebp, %ebx
146         movl    $SYS_futex, %eax
147         ENTER_KERNEL
148
149         movl    %eax, %edx
150
151         movl    $1, %eax
152         LOCK
153         xaddl   %eax, cond_lock-cond_nr_wakers(%ebp)
154         testl   %eax, %eax
155         jne     8f
156
157         cmpl    $-ETIMEDOUT, %edx
158         jne     9b
159
160 4:      movl    $ETIMEDOUT, %eax
161         jmp     2f
162
163 5:      decl    (%ebp)
164         xorl    %eax, %eax
165
166 2:      addl    $8, %esp
167         popl    %ebx
168         popl    %esi
169         popl    %edi
170         popl    %ebp
171         ret
172
173 6:      leal    cond_lock-cond_nr_wakers(%ebp), %eax
174         /* Preserves %ebx, %ecx, %edx, %edi, %esi.  */
175         call    __lll_mutex_unlock_wake
176         jmp     7b
177
178 8:      leal    cond_lock-cond_nr_wakers(%ebp), %ecx
179         /* Preserves %ebx, %edx, %edi, %esi.  */
180         call    __lll_mutex_lock_wait
181         jmp     5b
182
183 1:      movl    $EINVAL, %eax
184         ret
185         .size   __lll_cond_timedwait,.-__lll_cond_timedwait
186
187
188         .global __lll_cond_wake
189         .type   __lll_cond_wake,@function
190         .hidden __lll_cond_wake
191         .align  16
192 __lll_cond_wake:
193         pushl   %esi
194         pushl   %ebx
195
196         movl    %eax, %ebx
197
198         movl    $1, %eax
199         LOCK
200         xaddl   %eax, (%ebx)
201         testl   %eax, %eax
202         jne     1f
203
204 2:      leal    cond_nr_wakers(%ebx), %ebx
205         cmpl    $0, cond_nr_sleepers-cond_nr_wakers(%ebx)
206         je      3f
207
208         incl    (%ebx)
209         jz      5f
210
211 6:      movl    $FUTEX_WAKE, %ecx
212         xorl    %esi, %esi
213         movl    %ecx, %edx      /* movl $1, %edx */
214         movl    $SYS_futex, %eax
215         ENTER_KERNEL
216
217 3:      LOCK
218         decl    cond_lock-cond_nr_wakers(%ebx)
219         je,pt   4f
220
221         leal    cond_lock-cond_nr_wakers(%ebx), %eax
222         call    __lll_mutex_unlock_wake
223
224 4:      popl    %ebx
225         popl    %esi
226         ret
227
228 1:      movl    %ebx, %ecx
229         call    __lll_mutex_lock_wait
230         jmp     2b
231
232 5:      movl    $0x80000000, (%ebx)
233         jmp     6b
234         .size   __lll_cond_wake,.-__lll_cond_wake
235
236
237         .global __lll_cond_broadcast
238         .type   __lll_cond_broadcast,@function
239         .hidden __lll_cond_broadcast
240         .align  16
241 __lll_cond_broadcast:
242         pushl   %esi
243         pushl   %ebx
244
245         movl    %eax, %ebx
246         movl    $0x8000000, %edx
247
248         movl    $1, %eax
249         LOCK
250         xaddl   %eax, (%ebx)
251         testl   %eax, %eax
252         jne     1f
253
254 2:      leal    cond_nr_wakers(%ebx), %ebx
255         cmpl    $0, cond_nr_sleepers-cond_nr_wakers(%ebx)
256         je      3f
257
258         orl     %edx, (%ebx)
259
260 6:      movl    $FUTEX_WAKE, %ecx
261         xorl    %esi, %esi
262         movl    $SYS_futex, %eax
263         ENTER_KERNEL
264
265 3:      LOCK
266         decl    cond_lock-cond_nr_wakers(%ebx)
267         je,pt   4f
268
269         leal    cond_lock-cond_nr_wakers(%ebx), %eax
270         call    __lll_mutex_unlock_wake
271
272 4:      popl    %ebx
273         popl    %esi
274         ret
275
276 1:      movl    %ebx, %ecx
277         call    __lll_mutex_lock_wait
278         jmp     2b
279         .size   __lll_cond_broadcast,.-__lll_cond_broadcast