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