Argh! Use edx in PIC, not %ebx.
[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
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 ETIMEDOUT               110
30
31
32         .globl  __lll_lock_wait
33         .type   __lll_lock_wait,@function
34         .hidden __lll_lock_wait
35         .align  16
36 __lll_lock_wait:
37         pushl   %esi
38         pushl   %ebx
39         pushl   %edx
40
41         movl    %ecx, %ebx
42         xorl    %esi, %esi      /* No timeout.  */
43         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
44 1:
45         leal    -1(%eax), %edx  /* account for the preceeded xadd.  */
46         movl    $SYS_futex, %eax
47         int     $0x80
48
49         orl     $-1, %eax       /* Load -1.  */
50 #ifndef UP
51 # ifdef PIC
52         call    __i686.get_pc_thunk.dx
53         addl    $_GLOBAL_OFFSET_TABLE_, %edx
54         cmpl    $0, __libc_locking_needed@GOTOFF(%edx)
55 # else
56         cmpl    $0, __libc_locking_needed
57 # endif
58         je,pt   0f
59         lock
60 0:
61 #endif
62         xaddl   %eax, (%ebx)
63         jne     1b
64
65         movl    $-1, (%ebx)
66
67         popl    %edx
68         popl    %ebx
69         popl    %esi
70         ret
71         .size   __lll_lock_wait,.-__lll_lock_wait
72
73
74         .globl  lll_unlock_wake_cb
75         .type   lll_unlock_wake_cb,@function
76         .hidden lll_unlock_wake_cb
77         .align  16
78 lll_unlock_wake_cb:
79         pushl   %esi
80         pushl   %ebx
81         pushl   %ecx
82         pushl   %edx
83
84         movl    20(%esp), %ebx
85 #ifndef UP
86 # ifdef PIC
87         call    __i686.get_pc_thunk.dx
88         addl    $_GLOBAL_OFFSET_TABLE_, %edx
89         cmpl    $0, __libc_locking_needed@GOTOFF(%edx)
90 # else
91         cmpl    $0, __libc_locking_needed
92 # endif
93         je,pt   0f
94         lock
95 0:
96 #endif
97         incl    (%ebx)
98         jng     1f
99
100         popl    %edx
101         popl    %ecx
102         popl    %ebx
103         popl    %esi
104         ret
105         .size   lll_unlock_wake_cb,.-lll_unlock_wake_cb
106
107
108         .globl  __lll_unlock_wake
109         .type   __lll_unlock_wake,@function
110         .hidden __lll_unlock_wake
111 __lll_unlock_wake:
112         pushl   %esi
113         pushl   %ebx
114         pushl   %ecx
115         pushl   %edx
116
117         movl    %eax, %ebx
118 1:      movl    $FUTEX_WAKE, %ecx
119         movl    $1, %edx        /* Wake one thread.  */
120         xorl    %esi, %esi
121         movl    %edx, (%ebx)    /* Stores '$1'.  */
122         movl    $SYS_futex, %eax
123         int     $0x80
124
125         popl    %edx
126         popl    %ecx
127         popl    %ebx
128         popl    %esi
129         ret
130         .size   __lll_unlock_wake,.-__lll_unlock_wake
131
132
133         .globl  __lll_timedwait_tid
134         .type   __lll_timedwait_tid,@function
135         .hidden __lll_timedwait_tid
136 __lll_timedwait_tid:
137         pushl   %edi
138         pushl   %esi
139         pushl   %ebx
140         pushl   %ebp
141
142         movl    %eax, %ebp
143         movl    %edx, %edi
144         subl    $8, %esp
145
146         /* Get current time.  */
147 2:      movl    %esp, %ebx
148         xorl    %ecx, %ecx
149         movl    $SYS_gettimeofday, %eax
150         int     $0x80
151
152         /* Compute relative timeout.  */
153         movl    4(%esp), %eax
154         movl    $1000, %edx
155         mul     %edx            /* Milli seconds to nano seconds.  */
156         movl    (%edi), %ecx
157         movl    4(%edi), %edx
158         subl    (%esp), %ecx
159         subl    %eax, %edx
160         jns     5f
161         addl    $1000000000, %edx
162         decl    %ecx
163 5:      testl   %ecx, %ecx
164         js      6f              /* Time is already up.  */
165
166         movl    %ecx, (%esp)    /* Store relative timeout.  */
167         movl    %edx, 4(%esp)
168
169         movl    (%ebp), %edx
170         testl   %edx, %edx
171         jz      4f
172
173         movl    %esp, %esi
174         xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
175         movl    %ebp, %ebx
176         movl    $SYS_futex, %eax
177         int     $0x80
178
179         movl    %eax, %edx
180
181         cmpl    $0, (%ebx)
182         jne     1f
183 4:      xorl    %eax, %eax
184
185 3:      addl    $8, %esp
186         popl    %ebp
187         popl    %ebx
188         popl    %esi
189         popl    %edi
190         ret
191
192 1:      cmpl    $-ETIMEDOUT, %edx
193         jne     2b
194 6:      movl    $ETIMEDOUT, %eax
195         jmp     3b
196         .size   __lll_timedwait_tid,.-__lll_timedwait_tid
197
198
199         .section .gnu.linkonce.t.__i686.get_pc_thunk.dx,"ax",@progbits
200         .globl __i686.get_pc_thunk.dx
201         .hidden __i686.get_pc_thunk.dx
202         .type __i686.get_pc_thunk.dx,@function
203 __i686.get_pc_thunk.dx:
204         movl    (%esp), %edx
205         ret
206         .size   __i686.get_pc_thunk.dx,.-__i686.get_pc_thunk.dx