1 /* Copyright (C) 2002, 2003, 2004 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>
37 /* For the calculation see asm/vsyscall.h. */
38 #define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
41 .globl __lll_mutex_lock_wait
42 .type __lll_mutex_lock_wait,@function
43 .hidden __lll_mutex_lock_wait
45 __lll_mutex_lock_wait:
49 xorq %r10, %r10 /* No timeout. */
51 movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */
53 cmpl %edx, %eax /* NB: %edx == 2 */
56 1: movq $SYS_futex, %rax
60 xchgl %eax, (%rdi) /* NB: lock is implied */
68 .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
72 .globl __lll_mutex_timedlock_wait
73 .type __lll_mutex_timedlock_wait,@function
74 .hidden __lll_mutex_timedlock_wait
76 __lll_mutex_timedlock_wait:
77 /* Check for a valid timeout value. */
78 cmpq $1000000000, 8(%rdx)
87 /* Stack frame for the timespec and timeval structs. */
94 /* Get current time. */
97 movq $VSYSCALL_ADDR_vgettimeofday, %rax
98 /* This is a regular function call, all caller-save registers
99 might be clobbered. */
102 /* Compute relative timeout. */
105 mul %rdi /* Milli seconds to nano seconds. */
111 addq $1000000000, %rsi
114 js 5f /* Time is already up. */
117 movq %rdi, (%rsp) /* Store relative timeout. */
123 cmpxchgl %edx, (%r12)
129 xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
131 movq $SYS_futex, %rax
135 8: /* NB: %edx == 2 */
138 cmpxchgl %edx, (%rdi)
149 /* Check whether the time expired. */
150 7: cmpq $-ETIMEDOUT, %rcx
153 /* Make sure the current holder knows we are going to sleep. */
160 3: movl $EINVAL, %eax
163 5: movl $ETIMEDOUT, %eax
165 .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
170 .globl lll_unlock_wake_cb
171 .type lll_unlock_wake_cb,@function
172 .hidden lll_unlock_wake_cb
185 .size lll_unlock_wake_cb,.-lll_unlock_wake_cb
189 .globl __lll_mutex_unlock_wake
190 .type __lll_mutex_unlock_wake,@function
191 .hidden __lll_mutex_unlock_wake
193 __lll_mutex_unlock_wake:
198 movq $FUTEX_WAKE, %rsi
199 movl $1, %edx /* Wake one thread. */
200 movq $SYS_futex, %rax
206 .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
210 .globl __lll_timedwait_tid
211 .type __lll_timedwait_tid,@function
212 .hidden __lll_timedwait_tid
223 /* Get current time. */
226 movq $VSYSCALL_ADDR_vgettimeofday, %rax
229 /* Compute relative timeout. */
232 mul %rdi /* Milli seconds to nano seconds. */
238 addq $1000000000, %rsi
241 js 6f /* Time is already up. */
243 movq %rdi, (%rsp) /* Store relative timeout. */
251 xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
253 movq $SYS_futex, %rax
265 1: cmpq $-ETIMEDOUT, %rax
268 6: movl $ETIMEDOUT, %eax
270 .size __lll_timedwait_tid,.-__lll_timedwait_tid