]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/i386/lowlevellock.S
Assume LLL_LOCK_INITIALIZER is 0
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / lowlevellock.S
1 /* Copyright (C) 2002-2019 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, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <sysdep.h>
20 #include <pthread-errnos.h>
21 #include <kernel-features.h>
22 #include <lowlevellock.h>
23
24 #include <stap-probe.h>
25
26 .text
27
28 #define LOAD_PRIVATE_FUTEX_WAIT(reg) \
29 movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
30 #define LOAD_PRIVATE_FUTEX_WAKE(reg) \
31 movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
32 #define LOAD_FUTEX_WAIT(reg) \
33 xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
34 #define LOAD_FUTEX_WAIT_ABS(reg) \
35 xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg
36 #define LOAD_FUTEX_WAKE(reg) \
37 xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg
38
39 .globl __lll_lock_wait_private
40 .type __lll_lock_wait_private,@function
41 .hidden __lll_lock_wait_private
42 .align 16
43 __lll_lock_wait_private:
44 cfi_startproc
45 pushl %edx
46 cfi_adjust_cfa_offset(4)
47 pushl %ebx
48 cfi_adjust_cfa_offset(4)
49 pushl %esi
50 cfi_adjust_cfa_offset(4)
51 cfi_offset(%edx, -8)
52 cfi_offset(%ebx, -12)
53 cfi_offset(%esi, -16)
54
55 movl $2, %edx
56 movl %ecx, %ebx
57 xorl %esi, %esi /* No timeout. */
58 LOAD_PRIVATE_FUTEX_WAIT (%ecx)
59
60 cmpl %edx, %eax /* NB: %edx == 2 */
61 jne 2f
62
63 1: LIBC_PROBE (lll_lock_wait_private, 1, %ebx)
64 movl $SYS_futex, %eax
65 ENTER_KERNEL
66
67 2: movl %edx, %eax
68 xchgl %eax, (%ebx) /* NB: lock is implied */
69
70 testl %eax, %eax
71 jnz 1b
72
73 popl %esi
74 cfi_adjust_cfa_offset(-4)
75 cfi_restore(%esi)
76 popl %ebx
77 cfi_adjust_cfa_offset(-4)
78 cfi_restore(%ebx)
79 popl %edx
80 cfi_adjust_cfa_offset(-4)
81 cfi_restore(%edx)
82 ret
83 cfi_endproc
84 .size __lll_lock_wait_private,.-__lll_lock_wait_private
85
86 #if !IS_IN (libc)
87 .globl __lll_lock_wait
88 .type __lll_lock_wait,@function
89 .hidden __lll_lock_wait
90 .align 16
91 __lll_lock_wait:
92 cfi_startproc
93 pushl %edx
94 cfi_adjust_cfa_offset(4)
95 pushl %ebx
96 cfi_adjust_cfa_offset(4)
97 pushl %esi
98 cfi_adjust_cfa_offset(4)
99 cfi_offset(%edx, -8)
100 cfi_offset(%ebx, -12)
101 cfi_offset(%esi, -16)
102
103 movl %edx, %ebx
104 movl $2, %edx
105 xorl %esi, %esi /* No timeout. */
106 LOAD_FUTEX_WAIT (%ecx)
107
108 cmpl %edx, %eax /* NB: %edx == 2 */
109 jne 2f
110
111 1: movl $SYS_futex, %eax
112 ENTER_KERNEL
113
114 2: movl %edx, %eax
115 xchgl %eax, (%ebx) /* NB: lock is implied */
116
117 testl %eax, %eax
118 jnz 1b
119
120 popl %esi
121 cfi_adjust_cfa_offset(-4)
122 cfi_restore(%esi)
123 popl %ebx
124 cfi_adjust_cfa_offset(-4)
125 cfi_restore(%ebx)
126 popl %edx
127 cfi_adjust_cfa_offset(-4)
128 cfi_restore(%edx)
129 ret
130 cfi_endproc
131 .size __lll_lock_wait,.-__lll_lock_wait
132
133 /* %ecx: futex
134 %esi: flags
135 %edx: timeout
136 %eax: futex value
137 */
138 .globl __lll_timedlock_wait
139 .type __lll_timedlock_wait,@function
140 .hidden __lll_timedlock_wait
141 .align 16
142 __lll_timedlock_wait:
143 cfi_startproc
144 pushl %ebp
145 cfi_adjust_cfa_offset(4)
146 cfi_rel_offset(%ebp, 0)
147 pushl %ebx
148 cfi_adjust_cfa_offset(4)
149 cfi_rel_offset(%ebx, 0)
150
151 cmpl $0, (%edx)
152 js 8f
153
154 movl %ecx, %ebx
155 movl %esi, %ecx
156 movl %edx, %esi
157 movl $0xffffffff, %ebp
158 LOAD_FUTEX_WAIT_ABS (%ecx)
159
160 movl $2, %edx
161 cmpl %edx, %eax
162 jne 2f
163
164 1: movl $SYS_futex, %eax
165 movl $2, %edx
166 ENTER_KERNEL
167
168 2: xchgl %edx, (%ebx) /* NB: lock is implied */
169
170 testl %edx, %edx
171 jz 3f
172
173 cmpl $-ETIMEDOUT, %eax
174 je 4f
175 cmpl $-EINVAL, %eax
176 jne 1b
177 4: movl %eax, %edx
178 negl %edx
179
180 3: movl %edx, %eax
181 7: popl %ebx
182 cfi_adjust_cfa_offset(-4)
183 cfi_restore(%ebx)
184 popl %ebp
185 cfi_adjust_cfa_offset(-4)
186 cfi_restore(%ebp)
187 ret
188
189 8: movl $ETIMEDOUT, %eax
190 jmp 7b
191
192 cfi_endproc
193 .size __lll_timedlock_wait,.-__lll_timedlock_wait
194 #endif
195
196 .globl __lll_unlock_wake_private
197 .type __lll_unlock_wake_private,@function
198 .hidden __lll_unlock_wake_private
199 .align 16
200 __lll_unlock_wake_private:
201 cfi_startproc
202 pushl %ebx
203 cfi_adjust_cfa_offset(4)
204 pushl %ecx
205 cfi_adjust_cfa_offset(4)
206 pushl %edx
207 cfi_adjust_cfa_offset(4)
208 cfi_offset(%ebx, -8)
209 cfi_offset(%ecx, -12)
210 cfi_offset(%edx, -16)
211
212 movl %eax, %ebx
213 movl $0, (%eax)
214 LOAD_PRIVATE_FUTEX_WAKE (%ecx)
215 movl $1, %edx /* Wake one thread. */
216 movl $SYS_futex, %eax
217 ENTER_KERNEL
218
219 popl %edx
220 cfi_adjust_cfa_offset(-4)
221 cfi_restore(%edx)
222 popl %ecx
223 cfi_adjust_cfa_offset(-4)
224 cfi_restore(%ecx)
225 popl %ebx
226 cfi_adjust_cfa_offset(-4)
227 cfi_restore(%ebx)
228 ret
229 cfi_endproc
230 .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
231
232 #if !IS_IN (libc)
233 .globl __lll_unlock_wake
234 .type __lll_unlock_wake,@function
235 .hidden __lll_unlock_wake
236 .align 16
237 __lll_unlock_wake:
238 cfi_startproc
239 pushl %ebx
240 cfi_adjust_cfa_offset(4)
241 pushl %ecx
242 cfi_adjust_cfa_offset(4)
243 pushl %edx
244 cfi_adjust_cfa_offset(4)
245 cfi_offset(%ebx, -8)
246 cfi_offset(%ecx, -12)
247 cfi_offset(%edx, -16)
248
249 movl %eax, %ebx
250 movl $0, (%eax)
251 LOAD_FUTEX_WAKE (%ecx)
252 movl $1, %edx /* Wake one thread. */
253 movl $SYS_futex, %eax
254 ENTER_KERNEL
255
256 popl %edx
257 cfi_adjust_cfa_offset(-4)
258 cfi_restore(%edx)
259 popl %ecx
260 cfi_adjust_cfa_offset(-4)
261 cfi_restore(%ecx)
262 popl %ebx
263 cfi_adjust_cfa_offset(-4)
264 cfi_restore(%ebx)
265 ret
266 cfi_endproc
267 .size __lll_unlock_wake,.-__lll_unlock_wake
268 #endif