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.
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.
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.
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/>. */
20 #include <pthread-errnos.h>
21 #include <kernel-features.h>
22 #include <lowlevellock.h>
24 #include <stap-probe.h>
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
39 .globl __lll_lock_wait_private
40 .type __lll_lock_wait_private,@function
41 .hidden __lll_lock_wait_private
43 __lll_lock_wait_private:
46 cfi_adjust_cfa_offset(4)
48 cfi_adjust_cfa_offset(4)
50 cfi_adjust_cfa_offset(4)
57 xorl %esi, %esi /* No timeout. */
58 LOAD_PRIVATE_FUTEX_WAIT (%ecx)
60 cmpl %edx, %eax /* NB: %edx == 2 */
63 1: LIBC_PROBE (lll_lock_wait_private, 1, %ebx)
68 xchgl %eax, (%ebx) /* NB: lock is implied */
74 cfi_adjust_cfa_offset(-4)
77 cfi_adjust_cfa_offset(-4)
80 cfi_adjust_cfa_offset(-4)
84 .size __lll_lock_wait_private,.-__lll_lock_wait_private
87 .globl __lll_lock_wait
88 .type __lll_lock_wait,@function
89 .hidden __lll_lock_wait
94 cfi_adjust_cfa_offset(4)
96 cfi_adjust_cfa_offset(4)
98 cfi_adjust_cfa_offset(4)
100 cfi_offset(%ebx, -12)
101 cfi_offset(%esi, -16)
105 xorl %esi, %esi /* No timeout. */
106 LOAD_FUTEX_WAIT (%ecx)
108 cmpl %edx, %eax /* NB: %edx == 2 */
111 1: movl $SYS_futex, %eax
115 xchgl %eax, (%ebx) /* NB: lock is implied */
121 cfi_adjust_cfa_offset(-4)
124 cfi_adjust_cfa_offset(-4)
127 cfi_adjust_cfa_offset(-4)
131 .size __lll_lock_wait,.-__lll_lock_wait
138 .globl __lll_timedlock_wait
139 .type __lll_timedlock_wait,@function
140 .hidden __lll_timedlock_wait
142 __lll_timedlock_wait:
145 cfi_adjust_cfa_offset(4)
146 cfi_rel_offset(%ebp, 0)
148 cfi_adjust_cfa_offset(4)
149 cfi_rel_offset(%ebx, 0)
157 movl $0xffffffff, %ebp
158 LOAD_FUTEX_WAIT_ABS (%ecx)
164 1: movl $SYS_futex, %eax
168 2: xchgl %edx, (%ebx) /* NB: lock is implied */
173 cmpl $-ETIMEDOUT, %eax
182 cfi_adjust_cfa_offset(-4)
185 cfi_adjust_cfa_offset(-4)
189 8: movl $ETIMEDOUT, %eax
193 .size __lll_timedlock_wait,.-__lll_timedlock_wait
196 .globl __lll_unlock_wake_private
197 .type __lll_unlock_wake_private,@function
198 .hidden __lll_unlock_wake_private
200 __lll_unlock_wake_private:
203 cfi_adjust_cfa_offset(4)
205 cfi_adjust_cfa_offset(4)
207 cfi_adjust_cfa_offset(4)
209 cfi_offset(%ecx, -12)
210 cfi_offset(%edx, -16)
214 LOAD_PRIVATE_FUTEX_WAKE (%ecx)
215 movl $1, %edx /* Wake one thread. */
216 movl $SYS_futex, %eax
220 cfi_adjust_cfa_offset(-4)
223 cfi_adjust_cfa_offset(-4)
226 cfi_adjust_cfa_offset(-4)
230 .size __lll_unlock_wake_private,.-__lll_unlock_wake_private
233 .globl __lll_unlock_wake
234 .type __lll_unlock_wake,@function
235 .hidden __lll_unlock_wake
240 cfi_adjust_cfa_offset(4)
242 cfi_adjust_cfa_offset(4)
244 cfi_adjust_cfa_offset(4)
246 cfi_offset(%ecx, -12)
247 cfi_offset(%edx, -16)
251 LOAD_FUTEX_WAKE (%ecx)
252 movl $1, %edx /* Wake one thread. */
253 movl $SYS_futex, %eax
257 cfi_adjust_cfa_offset(-4)
260 cfi_adjust_cfa_offset(-4)
263 cfi_adjust_cfa_offset(-4)
267 .size __lll_unlock_wake,.-__lll_unlock_wake