1
/* Copyright (C) 2002-2005,2007,2009,2010,2011 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 <lowlevellock.h>
21
#include <lowlevelrwlock.h>
22
#include <pthread-errnos.h>
23
#include <kernel-features.h>
27
.globl pthread_rwlock_timedrdlock
28
.type pthread_rwlock_timedrdlock,@function
30
pthread_rwlock_timedrdlock:
33
cfi_adjust_cfa_offset(8)
34
cfi_rel_offset(%r12, 0)
36
cfi_adjust_cfa_offset(8)
37
cfi_rel_offset(%r13, 0)
38
#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
42
cfi_adjust_cfa_offset(8)
43
cfi_rel_offset(%r14, 0)
46
cfi_adjust_cfa_offset(16)
60
cmpxchgl %esi, MUTEX(%rdi)
64
2: movl WRITER(%r12), %eax
67
cmpl $0, WRITERS_QUEUED(%r12)
72
/* Check the value of the timeout parameter. */
73
3: cmpq $1000000000, 8(%r13)
76
incl READERS_QUEUED(%r12)
79
movl READERS_WAKEUP(%r12), VALREG
91
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
93
cmpl $0, __have_futex_clock_realtime(%rip)
95
cmpl $0, __have_futex_clock_realtime
101
js 16f /* Time is already up. */
103
movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
104
xorl PSHARED(%r12), %esi
106
movl $0xffffffff, %r9d
107
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
110
21: leaq READERS_WAKEUP(%r12), %rdi
111
movl $SYS_futex, %eax
115
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
118
/* Get current time. */
121
/* This call works because we directly jump to a system call entry
122
which preserves all the registers. */
123
call JUMPTARGET(__gettimeofday)
125
/* Compute relative timeout. */
128
mul %rdi /* Milli seconds to nano seconds. */
134
addq $1000000000, %rdi
137
js 16f /* Time is already up. */
140
movq %rcx, (%rsp) /* Store relative timeout. */
143
# ifdef __ASSUME_PRIVATE_FUTEX
144
movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
145
xorl PSHARED(%r12), %esi
148
movl PSHARED(%r12), %esi
150
movl $FUTEX_WAIT, %esi
151
orl PSHARED(%r12), %esi
153
xorl %fs:PRIVATE_FUTEX, %esi
162
17: /* Reget the lock. */
167
cmpxchgl %esi, (%r12)
169
cmpxchgl %esi, MUTEX(%r12)
173
13: decl READERS_QUEUED(%r12)
174
cmpq $-ETIMEDOUT, %rdx
177
18: movl $ETIMEDOUT, %edx
182
incl NR_READERS(%r12)
194
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
196
cfi_adjust_cfa_offset(-16)
198
cfi_adjust_cfa_offset(-8)
202
cfi_adjust_cfa_offset(-8)
205
cfi_adjust_cfa_offset(-8)
209
#ifdef __ASSUME_PRIVATE_FUTEX
210
cfi_adjust_cfa_offset(16)
211
cfi_rel_offset(%r12, 8)
212
cfi_rel_offset(%r13, 0)
214
cfi_adjust_cfa_offset(40)
215
cfi_offset(%r12, -16)
216
cfi_offset(%r13, -24)
217
cfi_offset(%r14, -32)
219
1: movl PSHARED(%rdi), %esi
223
callq __lll_lock_wait
226
14: cmpl %fs:TID, %eax
231
6: movl PSHARED(%r12), %esi
235
leal MUTEX(%r12), %rdi
237
callq __lll_unlock_wake
241
8: decl NR_READERS(%r12)
246
4: decl READERS_QUEUED(%r12)
250
10: movl PSHARED(%r12), %esi
254
leaq MUTEX(%r12), %rdi
256
callq __lll_unlock_wake
259
12: movl PSHARED(%r12), %esi
263
leaq MUTEX(%r12), %rdi
265
callq __lll_lock_wait
268
16: movq $-ETIMEDOUT, %rdx
271
19: movl $EINVAL, %edx
274
.size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock