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