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>
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:
48 cfi_adjust_cfa_offset(8)
50 cfi_adjust_cfa_offset(8)
53 xorq %r10, %r10 /* No timeout. */
58 movl $FUTEX_WAIT, %esi
61 cmpl %edx, %eax /* NB: %edx == 2 */
64 1: movl $SYS_futex, %eax
68 xchgl %eax, (%rdi) /* NB: lock is implied */
74 cfi_adjust_cfa_offset(-8)
77 cfi_adjust_cfa_offset(-8)
81 .size __lll_mutex_lock_wait,.-__lll_mutex_lock_wait
85 .globl __lll_mutex_timedlock_wait
86 .type __lll_mutex_timedlock_wait,@function
87 .hidden __lll_mutex_timedlock_wait
89 __lll_mutex_timedlock_wait:
91 /* Check for a valid timeout value. */
92 cmpq $1000000000, 8(%rdx)
96 cfi_adjust_cfa_offset(8)
98 cfi_adjust_cfa_offset(8)
100 cfi_adjust_cfa_offset(8)
102 cfi_adjust_cfa_offset(8)
104 cfi_adjust_cfa_offset(8)
107 cfi_offset(%r12, -32)
108 cfi_offset(%r13, -40)
109 cfi_offset(%r14, -48)
111 /* Stack frame for the timespec and timeval structs. */
113 cfi_adjust_cfa_offset(16)
119 /* Get current time. */
122 movq $VSYSCALL_ADDR_vgettimeofday, %rax
123 /* This is a regular function call, all caller-save registers
124 might be clobbered. */
127 /* Compute relative timeout. */
130 mul %rdi /* Milli seconds to nano seconds. */
136 addq $1000000000, %rsi
139 js 5f /* Time is already up. */
142 movq %rdi, (%rsp) /* Store relative timeout. */
148 cmpxchgl %edx, (%r12)
157 movl $FUTEX_WAIT, %esi
160 movl $SYS_futex, %eax
164 8: /* NB: %edx == 2 */
167 cmpxchgl %edx, (%rdi)
171 cfi_adjust_cfa_offset(-16)
173 cfi_adjust_cfa_offset(-8)
176 cfi_adjust_cfa_offset(-8)
179 cfi_adjust_cfa_offset(-8)
182 cfi_adjust_cfa_offset(-8)
185 cfi_adjust_cfa_offset(-8)
189 3: movl $EINVAL, %eax
192 cfi_adjust_cfa_offset(56)
195 cfi_offset(%r12, -32)
196 cfi_offset(%r13, -40)
197 cfi_offset(%r14, -48)
198 /* Check whether the time expired. */
199 7: cmpq $-ETIMEDOUT, %rcx
202 /* Make sure the current holder knows we are going to sleep. */
209 5: movl $ETIMEDOUT, %eax
212 .size __lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
217 .globl lll_unlock_wake_cb
218 .type lll_unlock_wake_cb,@function
219 .hidden lll_unlock_wake_cb
232 .size lll_unlock_wake_cb,.-lll_unlock_wake_cb
236 .globl __lll_mutex_unlock_wake
237 .type __lll_mutex_unlock_wake,@function
238 .hidden __lll_mutex_unlock_wake
240 __lll_mutex_unlock_wake:
243 cfi_adjust_cfa_offset(8)
245 cfi_adjust_cfa_offset(8)
246 cfi_offset(%rsi, -16)
247 cfi_offset(%rdx, -24)
250 movl $FUTEX_WAKE, %esi
251 movl $1, %edx /* Wake one thread. */
252 movl $SYS_futex, %eax
256 cfi_adjust_cfa_offset(-8)
259 cfi_adjust_cfa_offset(-8)
263 .size __lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
267 .globl __lll_timedwait_tid
268 .type __lll_timedwait_tid,@function
269 .hidden __lll_timedwait_tid
280 /* Get current time. */
283 movq $VSYSCALL_ADDR_vgettimeofday, %rax
286 /* Compute relative timeout. */
289 mul %rdi /* Milli seconds to nano seconds. */
295 addq $1000000000, %rsi
298 js 6f /* Time is already up. */
300 movq %rdi, (%rsp) /* Store relative timeout. */
311 movl $FUTEX_WAIT, %esi
314 movl $SYS_futex, %eax
326 1: cmpq $-ETIMEDOUT, %rax
329 6: movl $ETIMEDOUT, %eax
331 .size __lll_timedwait_tid,.-__lll_timedwait_tid