]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
Add adaptive elision to rwlocks
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_timedrdlock.S
CommitLineData
d4697bc9 1/* Copyright (C) 2002-2014 Free Software Foundation, Inc.
d0369fb8
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
d0369fb8
UD
18
19#include <sysdep.h>
e51deae7 20#include <lowlevellock.h>
d0369fb8
UD
21#include <lowlevelrwlock.h>
22#include <pthread-errnos.h>
28635aca 23#include <kernel-features.h>
d0369fb8 24
d0369fb8
UD
25 .text
26
27 .globl pthread_rwlock_timedrdlock
28 .type pthread_rwlock_timedrdlock,@function
29 .align 16
30pthread_rwlock_timedrdlock:
62605cbf 31 cfi_startproc
92ed3daf 32 pushq %r12
62605cbf 33 cfi_adjust_cfa_offset(8)
32c6c342 34 cfi_rel_offset(%r12, 0)
92ed3daf 35 pushq %r13
62605cbf 36 cfi_adjust_cfa_offset(8)
32c6c342
UD
37 cfi_rel_offset(%r13, 0)
38#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
39# define VALREG %edx
40#else
51d0678c 41 pushq %r14
62605cbf 42 cfi_adjust_cfa_offset(8)
32c6c342 43 cfi_rel_offset(%r14, 0)
62605cbf 44
d0369fb8 45 subq $16, %rsp
62605cbf 46 cfi_adjust_cfa_offset(16)
32c6c342
UD
47# define VALREG %r14d
48#endif
d0369fb8 49
92ed3daf
UD
50 movq %rdi, %r12
51 movq %rsi, %r13
d0369fb8
UD
52
53 /* Get the lock. */
54 movl $1, %esi
3a226d33 55 xorl %eax, %eax
d0369fb8
UD
56 LOCK
57#if MUTEX == 0
3a226d33 58 cmpxchgl %esi, (%rdi)
d0369fb8 59#else
3a226d33 60 cmpxchgl %esi, MUTEX(%rdi)
d0369fb8 61#endif
3a226d33 62 jnz 1f
d0369fb8 63
4ad0bbf4
UD
642: movl WRITER(%r12), %eax
65 testl %eax, %eax
d0369fb8 66 jne 14f
92ed3daf 67 cmpl $0, WRITERS_QUEUED(%r12)
d0369fb8 68 je 5f
92ed3daf 69 cmpl $0, FLAGS(%r12)
d0369fb8
UD
70 je 5f
71
72 /* Check the value of the timeout parameter. */
38205402 733: cmpq $1000000000, 8(%r13)
d0369fb8
UD
74 jae 19f
75
92ed3daf 76 incl READERS_QUEUED(%r12)
d0369fb8
UD
77 je 4f
78
32c6c342 79 movl READERS_WAKEUP(%r12), VALREG
d0369fb8
UD
80
81 /* Unlock. */
82 LOCK
83#if MUTEX == 0
51d0678c 84 decl (%r12)
d0369fb8 85#else
51d0678c 86 decl MUTEX(%r12)
d0369fb8
UD
87#endif
88 jne 10f
89
32c6c342
UD
9011:
91#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
92# ifdef PIC
93 cmpl $0, __have_futex_clock_realtime(%rip)
94# else
95 cmpl $0, __have_futex_clock_realtime
96# endif
97 je .Lreltmo
98#endif
99
2983d85e
AS
100 cmpq $0, (%r13)
101 js 16f /* Time is already up. */
102
32c6c342
UD
103 movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
104 xorl PSHARED(%r12), %esi
105 movq %r13, %r10
106 movl $0xffffffff, %r9d
107#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
108 movl %r14d, %edx
109#endif
11021: leaq READERS_WAKEUP(%r12), %rdi
111 movl $SYS_futex, %eax
112 syscall
113 movq %rax, %rdx
114
115#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
116 .subsection 2
117.Lreltmo:
d0369fb8 118 /* Get current time. */
32c6c342 119 movq %rsp, %rdi
ee618985 120 xorl %esi, %esi
9e5c9dcd
UD
121 /* This call works because we directly jump to a system call entry
122 which preserves all the registers. */
123 call JUMPTARGET(__gettimeofday)
d0369fb8
UD
124
125 /* Compute relative timeout. */
126 movq 8(%rsp), %rax
ee618985 127 movl $1000, %edi
d0369fb8 128 mul %rdi /* Milli seconds to nano seconds. */
92ed3daf
UD
129 movq (%r13), %rcx
130 movq 8(%r13), %rdi
d0369fb8
UD
131 subq (%rsp), %rcx
132 subq %rax, %rdi
133 jns 15f
134 addq $1000000000, %rdi
135 decq %rcx
13615: testq %rcx, %rcx
137 js 16f /* Time is already up. */
138
139 /* Futex call. */
140 movq %rcx, (%rsp) /* Store relative timeout. */
141 movq %rdi, 8(%rsp)
142
32c6c342 143# ifdef __ASSUME_PRIVATE_FUTEX
50f1dec5 144 movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi
eb4f5909 145 xorl PSHARED(%r12), %esi
50f1dec5 146# else
32c6c342
UD
147# if FUTEX_WAIT == 0
148 movl PSHARED(%r12), %esi
149# else
ee618985 150 movl $FUTEX_WAIT, %esi
50f1dec5 151 orl PSHARED(%r12), %esi
32c6c342 152# endif
50f1dec5 153 xorl %fs:PRIVATE_FUTEX, %esi
32c6c342 154# endif
51d0678c
UD
155 movq %rsp, %r10
156 movl %r14d, %edx
d0369fb8 157
32c6c342
UD
158 jmp 21b
159 .previous
160#endif
161
16217: /* Reget the lock. */
d0369fb8 163 movl $1, %esi
3a226d33 164 xorl %eax, %eax
d0369fb8
UD
165 LOCK
166#if MUTEX == 0
3a226d33 167 cmpxchgl %esi, (%r12)
d0369fb8 168#else
3a226d33 169 cmpxchgl %esi, MUTEX(%r12)
d0369fb8 170#endif
3a226d33 171 jnz 12f
d0369fb8 172
92ed3daf 17313: decl READERS_QUEUED(%r12)
d0369fb8
UD
174 cmpq $-ETIMEDOUT, %rdx
175 jne 2b
176
ee618985 17718: movl $ETIMEDOUT, %edx
d0369fb8
UD
178 jmp 9f
179
180
ee618985 1815: xorl %edx, %edx
92ed3daf 182 incl NR_READERS(%r12)
d0369fb8
UD
183 je 8f
1849: LOCK
185#if MUTEX == 0
92ed3daf 186 decl (%r12)
d0369fb8 187#else
92ed3daf 188 decl MUTEX(%r12)
d0369fb8
UD
189#endif
190 jne 6f
191
92ed3daf 1927: movq %rdx, %rax
d0369fb8 193
32c6c342 194#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
d0369fb8 195 addq $16, %rsp
62605cbf 196 cfi_adjust_cfa_offset(-16)
51d0678c 197 popq %r14
62605cbf
UD
198 cfi_adjust_cfa_offset(-8)
199 cfi_restore(%r14)
32c6c342 200#endif
92ed3daf 201 popq %r13
62605cbf
UD
202 cfi_adjust_cfa_offset(-8)
203 cfi_restore(%r13)
92ed3daf 204 popq %r12
62605cbf
UD
205 cfi_adjust_cfa_offset(-8)
206 cfi_restore(%r12)
d0369fb8
UD
207 retq
208
32c6c342
UD
209#ifdef __ASSUME_PRIVATE_FUTEX
210 cfi_adjust_cfa_offset(16)
211 cfi_rel_offset(%r12, 8)
212 cfi_rel_offset(%r13, 0)
213#else
62605cbf
UD
214 cfi_adjust_cfa_offset(40)
215 cfi_offset(%r12, -16)
216 cfi_offset(%r13, -24)
217 cfi_offset(%r14, -32)
32c6c342 218#endif
e51deae7 2191: movl PSHARED(%rdi), %esi
d0369fb8
UD
220#if MUTEX != 0
221 addq $MUTEX, %rdi
222#endif
e51deae7 223 callq __lll_lock_wait
d0369fb8
UD
224 jmp 2b
225
4ad0bbf4 22614: cmpl %fs:TID, %eax
d0369fb8 227 jne 3b
ee618985 228 movl $EDEADLK, %edx
d0369fb8
UD
229 jmp 9b
230
e51deae7 2316: movl PSHARED(%r12), %esi
d0369fb8 232#if MUTEX == 0
92ed3daf 233 movq %r12, %rdi
d0369fb8 234#else
92ed3daf 235 leal MUTEX(%r12), %rdi
d0369fb8 236#endif
e51deae7 237 callq __lll_unlock_wake
d0369fb8
UD
238 jmp 7b
239
240 /* Overflow. */
92ed3daf 2418: decl NR_READERS(%r12)
ee618985 242 movl $EAGAIN, %edx
d0369fb8
UD
243 jmp 9b
244
245 /* Overflow. */
92ed3daf 2464: decl READERS_QUEUED(%r12)
ee618985 247 movl $EAGAIN, %edx
d0369fb8
UD
248 jmp 9b
249
e51deae7 25010: movl PSHARED(%r12), %esi
d0369fb8 251#if MUTEX == 0
92ed3daf 252 movq %r12, %rdi
d0369fb8 253#else
92ed3daf 254 leaq MUTEX(%r12), %rdi
d0369fb8 255#endif
e51deae7 256 callq __lll_unlock_wake
d0369fb8
UD
257 jmp 11b
258
e51deae7 25912: movl PSHARED(%r12), %esi
d0369fb8 260#if MUTEX == 0
92ed3daf 261 movq %r12, %rdi
d0369fb8 262#else
92ed3daf 263 leaq MUTEX(%r12), %rdi
d0369fb8 264#endif
e51deae7 265 callq __lll_lock_wait
d0369fb8
UD
266 jmp 13b
267
26816: movq $-ETIMEDOUT, %rdx
269 jmp 17b
270
ee618985 27119: movl $EINVAL, %edx
d0369fb8 272 jmp 9b
62605cbf 273 cfi_endproc
d0369fb8 274 .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock