1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #include <pthread-errnos.h>
22 #include <lowlevelrobustlock.h>
37 #define FUTEX_WAITERS 0x80000000
38 #define FUTEX_OWNER_DIED 0x40000000
40 /* For the calculation see asm/vsyscall.h. */
41 #define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
44 .globl __lll_robust_mutex_lock_wait
45 .type __lll_robust_mutex_lock_wait,@function
46 .hidden __lll_robust_mutex_lock_wait
48 __lll_robust_mutex_lock_wait:
51 cfi_adjust_cfa_offset(8)
53 cfi_adjust_cfa_offset(8)
57 xorq %r10, %r10 /* No timeout. */
61 movl $FUTEX_WAIT, %esi
65 orl $FUTEX_WAITERS, %edx
67 testl $FUTEX_OWNER_DIED, %eax
77 1: movl $SYS_futex, %eax
86 orl $FUTEX_WAITERS, %edx
93 cfi_adjust_cfa_offset(-8)
96 cfi_adjust_cfa_offset(-8)
100 .size __lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
103 .globl __lll_robust_mutex_timedlock_wait
104 .type __lll_robust_mutex_timedlock_wait,@function
105 .hidden __lll_robust_mutex_timedlock_wait
107 __lll_robust_mutex_timedlock_wait:
109 /* Check for a valid timeout value. */
110 cmpq $1000000000, 8(%rdx)
114 cfi_adjust_cfa_offset(8)
116 cfi_adjust_cfa_offset(8)
118 cfi_adjust_cfa_offset(8)
120 cfi_adjust_cfa_offset(8)
123 cfi_offset(%r12, -32)
124 cfi_offset(%r13, -40)
126 /* Stack frame for the timespec and timeval structs. */
128 cfi_adjust_cfa_offset(24)
133 1: movq %rax, 16(%rsp)
135 /* Get current time. */
138 movq $VSYSCALL_ADDR_vgettimeofday, %rax
139 /* This is a regular function call, all caller-save registers
140 might be clobbered. */
143 /* Compute relative timeout. */
146 mul %rdi /* Milli seconds to nano seconds. */
152 addq $1000000000, %rsi
155 js 8f /* Time is already up. */
158 movq %rdi, (%rsp) /* Store relative timeout. */
163 orl $FUTEX_WAITERS, %edx
165 testl $FUTEX_OWNER_DIED, %eax
172 cmpxchgl %edx, (%r12)
173 movq $0, %rcx /* Must use mov to avoid changing cc. */
180 movl $FUTEX_WAIT, %esi
183 movl $SYS_futex, %eax
193 orl $FUTEX_WAITERS, %edx
195 cmpxchgl %edx, (%r12)
199 cfi_adjust_cfa_offset(-24)
201 cfi_adjust_cfa_offset(-8)
204 cfi_adjust_cfa_offset(-8)
207 cfi_adjust_cfa_offset(-8)
210 cfi_adjust_cfa_offset(-8)
214 3: movl $EINVAL, %eax
217 cfi_adjust_cfa_offset(56)
220 cfi_offset(%r12, -32)
221 cfi_offset(%r13, -40)
222 /* Check whether the time expired. */
223 7: cmpq $-ETIMEDOUT, %rcx
226 8: movl $ETIMEDOUT, %eax
229 .size __lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait