Unconditionally include <dl-sysdep.h>.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / i386 / i486 / libc-lowlevelmutex.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 #define SYS_gettimeofday        __NR_gettimeofday
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
28
29 #define EWOULDBLOCK             11
30 #define EINVAL                  22
31 #define ETIMEDOUT               110
32
33
34         .globl  __lll_mutex_lock_wait
35         .type   __lll_mutex_lock_wait,@function
36         .hidden __lll_mutex_lock_wait
37         .align  16
38 __lll_mutex_lock_wait:
39         pushl   %esi
40         pushl   %ebx
41         pushl   %edx
42
43         movl    %ecx, %ebx
44         xorl    %esi, %esi      /* No timeout.  */
45         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
46 1:
47         leal    1(%eax), %edx   /* account for the preceeded xadd.  */
48         movl    $SYS_futex, %eax
49         int     $0x80
50
51         movl    $1, %eax
52 #ifndef UP
53         cmpl    $0, %gs:MULTIPLE_THREADS_OFFSET
54         je,pt   0f
55         lock
56 0:
57 #endif
58         xaddl   %eax, (%ebx)
59         testl   %eax, %eax
60         jne     1b
61
62         movl    $2, (%ebx)
63
64         popl    %edx
65         popl    %ebx
66         popl    %esi
67         ret
68         .size   __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
69
70
71         .globl  __lll_mutex_timedlock_wait
72         .type   __lll_mutex_timedlock_wait,@function
73         .hidden __lll_mutex_timedlock_wait
74         .align  16
75 __lll_mutex_timedlock_wait:
76         /* Check for a valid timeout value.  */
77         cmpl    $1000000000, 4(%edx)
78         jae     3f
79
80         pushl   %edi
81         pushl   %esi
82         pushl   %ebx
83         pushl   %ebp
84
85         /* Stack frame for the timespec and timeval structs.  */
86         subl    $8, %esp
87
88         movl    %ecx, %ebp
89         movl    %edx, %edi
90         leal    1(%eax), %esi
91
92         /* Get current time.  */
93 1:
94         movl    %esp, %ebx
95         xorl    %ecx, %ecx
96         movl    $SYS_gettimeofday, %eax
97         int     $0x80
98
99         /* Compute relative timeout.  */
100         movl    4(%esp), %eax
101         movl    $1000, %edx
102         mul     %edx            /* Milli seconds to nano seconds.  */
103         movl    (%edi), %ecx
104         movl    4(%edi), %edx
105         subl    (%esp), %ecx
106         subl    %eax, %edx
107         jns     4f
108         addl    $1000000000, %edx
109         decl    %ecx
110 4:      testl   %ecx, %ecx
111         js      5f              /* Time is already up.  */
112
113         /* Futex call.  */
114         movl    %ecx, (%esp)    /* Store relative timeout.  */
115         movl    %edx, 4(%esp)
116         movl    %esi, %edx
117         movl    %esp, %esi
118         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
119         movl    %ebp, %ebx
120         movl    $SYS_futex, %eax
121         int     $0x80
122
123         movl    $1, %esi
124 #ifndef UP
125         cmpl    $0, %gs:MULTIPLE_THREADS_OFFSET
126         je,pt   0f
127         lock
128 0:
129 #endif
130         xaddl   %esi, (%ebx)
131         testl   %esi, %esi
132         jne     7f
133
134         movl    $2, (%ebx)
135         xorl    %eax, %eax
136
137 6:      addl    $8, %esp
138         popl    %ebp
139         popl    %ebx
140         popl    %esi
141         popl    %edi
142         ret
143
144         /* Check whether the time expired.  */
145 7:      cmpl    $-ETIMEDOUT, %eax
146         je      5f
147         jmp     1b
148
149 3:      movl    $EINVAL, %eax
150         ret
151
152 5:      movl    $ETIMEDOUT, %eax
153         jmp     6b
154         .size   __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
155
156
157         .globl  __lll_mutex_unlock_wake
158         .type   __lll_mutex_unlock_wake,@function
159         .hidden __lll_mutex_unlock_wake
160         .align  16
161 __lll_mutex_unlock_wake:
162         pushl   %esi
163         pushl   %ebx
164         pushl   %ecx
165         pushl   %edx
166
167         movl    $FUTEX_WAKE, %ecx
168         movl    %eax, %ebx
169         xorl    %esi, %esi
170         movl    $0, (%ebx)
171         movl    $1, %edx        /* Wake one thread.  */
172         movl    $SYS_futex, %eax
173         int     $0x80
174
175         popl    %edx
176         popl    %ecx
177         popl    %ebx
178         popl    %esi
179         ret
180         .size   __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake