]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S
2.5-18.1
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_timedrdlock.S
CommitLineData
0ecb606c 1/* Copyright (C) 2002, 2003, 2004, 2005 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
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
18 02111-1307 USA. */
19
20#include <sysdep.h>
21#include <lowlevelrwlock.h>
22#include <pthread-errnos.h>
23
24
d0369fb8
UD
25#define SYS_futex 202
26#define FUTEX_WAIT 0
27#define FUTEX_WAKE 1
28
92ed3daf
UD
29/* For the calculation see asm/vsyscall.h. */
30#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
31
32
d0369fb8
UD
33#ifndef UP
34# define LOCK lock
35#else
36# define LOCK
37#endif
38
39
40 .text
41
42 .globl pthread_rwlock_timedrdlock
43 .type pthread_rwlock_timedrdlock,@function
44 .align 16
45pthread_rwlock_timedrdlock:
92ed3daf
UD
46 pushq %r12
47 pushq %r13
51d0678c 48 pushq %r14
d0369fb8
UD
49 subq $16, %rsp
50
92ed3daf
UD
51 movq %rdi, %r12
52 movq %rsi, %r13
d0369fb8
UD
53
54 /* Get the lock. */
55 movl $1, %esi
3a226d33 56 xorl %eax, %eax
d0369fb8
UD
57 LOCK
58#if MUTEX == 0
3a226d33 59 cmpxchgl %esi, (%rdi)
d0369fb8 60#else
3a226d33 61 cmpxchgl %esi, MUTEX(%rdi)
d0369fb8 62#endif
3a226d33 63 jnz 1f
d0369fb8 64
4ad0bbf4
UD
652: movl WRITER(%r12), %eax
66 testl %eax, %eax
d0369fb8 67 jne 14f
92ed3daf 68 cmpl $0, WRITERS_QUEUED(%r12)
d0369fb8 69 je 5f
92ed3daf 70 cmpl $0, FLAGS(%r12)
d0369fb8
UD
71 je 5f
72
73 /* Check the value of the timeout parameter. */
38205402 743: cmpq $1000000000, 8(%r13)
d0369fb8
UD
75 jae 19f
76
92ed3daf 77 incl READERS_QUEUED(%r12)
d0369fb8
UD
78 je 4f
79
51d0678c 80 movl READERS_WAKEUP(%r12), %r14d
d0369fb8
UD
81
82 /* Unlock. */
83 LOCK
84#if MUTEX == 0
51d0678c 85 decl (%r12)
d0369fb8 86#else
51d0678c 87 decl MUTEX(%r12)
d0369fb8
UD
88#endif
89 jne 10f
90
91 /* Get current time. */
9211: movq %rsp, %rdi
0ecb606c 93 xorl %esi, %esi
92ed3daf
UD
94 movq $VSYSCALL_ADDR_vgettimeofday, %rax
95 callq *%rax
d0369fb8
UD
96
97 /* Compute relative timeout. */
98 movq 8(%rsp), %rax
0ecb606c 99 movl $1000, %edi
d0369fb8 100 mul %rdi /* Milli seconds to nano seconds. */
92ed3daf
UD
101 movq (%r13), %rcx
102 movq 8(%r13), %rdi
d0369fb8
UD
103 subq (%rsp), %rcx
104 subq %rax, %rdi
105 jns 15f
106 addq $1000000000, %rdi
107 decq %rcx
10815: testq %rcx, %rcx
109 js 16f /* Time is already up. */
110
111 /* Futex call. */
112 movq %rcx, (%rsp) /* Store relative timeout. */
113 movq %rdi, 8(%rsp)
114
0ecb606c
JJ
115#if FUTEX_WAIT == 0
116 xorl %esi, %esi
117#else
118 movl $FUTEX_WAIT, %esi
119#endif
51d0678c
UD
120 movq %rsp, %r10
121 movl %r14d, %edx
92ed3daf 122 leaq READERS_WAKEUP(%r12), %rdi
0ecb606c 123 movl $SYS_futex, %eax
d0369fb8
UD
124 syscall
125 movq %rax, %rdx
12617:
127
128 /* Reget the lock. */
129 movl $1, %esi
3a226d33 130 xorl %eax, %eax
d0369fb8
UD
131 LOCK
132#if MUTEX == 0
3a226d33 133 cmpxchgl %esi, (%r12)
d0369fb8 134#else
3a226d33 135 cmpxchgl %esi, MUTEX(%r12)
d0369fb8 136#endif
3a226d33 137 jnz 12f
d0369fb8 138
92ed3daf 13913: decl READERS_QUEUED(%r12)
d0369fb8
UD
140 cmpq $-ETIMEDOUT, %rdx
141 jne 2b
142
0ecb606c 14318: movl $ETIMEDOUT, %edx
d0369fb8
UD
144 jmp 9f
145
146
0ecb606c 1475: xorl %edx, %edx
92ed3daf 148 incl NR_READERS(%r12)
d0369fb8
UD
149 je 8f
1509: LOCK
151#if MUTEX == 0
92ed3daf 152 decl (%r12)
d0369fb8 153#else
92ed3daf 154 decl MUTEX(%r12)
d0369fb8
UD
155#endif
156 jne 6f
157
92ed3daf 1587: movq %rdx, %rax
d0369fb8
UD
159
160 addq $16, %rsp
51d0678c 161 popq %r14
92ed3daf
UD
162 popq %r13
163 popq %r12
d0369fb8
UD
164 retq
165
1661:
167#if MUTEX != 0
168 addq $MUTEX, %rdi
169#endif
170 callq __lll_mutex_lock_wait
171 jmp 2b
172
4ad0bbf4 17314: cmpl %fs:TID, %eax
d0369fb8 174 jne 3b
0ecb606c 175 movl $EDEADLK, %edx
d0369fb8
UD
176 jmp 9b
177
1786:
179#if MUTEX == 0
92ed3daf 180 movq %r12, %rdi
d0369fb8 181#else
92ed3daf 182 leal MUTEX(%r12), %rdi
d0369fb8
UD
183#endif
184 callq __lll_mutex_unlock_wake
185 jmp 7b
186
187 /* Overflow. */
92ed3daf 1888: decl NR_READERS(%r12)
0ecb606c 189 movl $EAGAIN, %edx
d0369fb8
UD
190 jmp 9b
191
192 /* Overflow. */
92ed3daf 1934: decl READERS_QUEUED(%r12)
0ecb606c 194 movl $EAGAIN, %edx
d0369fb8
UD
195 jmp 9b
196
19710:
198#if MUTEX == 0
92ed3daf 199 movq %r12, %rdi
d0369fb8 200#else
92ed3daf 201 leaq MUTEX(%r12), %rdi
d0369fb8
UD
202#endif
203 callq __lll_mutex_unlock_wake
204 jmp 11b
205
20612:
207#if MUTEX == 0
92ed3daf 208 movq %r12, %rdi
d0369fb8 209#else
92ed3daf 210 leaq MUTEX(%r12), %rdi
d0369fb8 211#endif
92ed3daf 212 callq __lll_mutex_lock_wait
d0369fb8
UD
213 jmp 13b
214
21516: movq $-ETIMEDOUT, %rdx
216 jmp 17b
217
0ecb606c 21819: movl $EINVAL, %edx
d0369fb8
UD
219 jmp 9b
220 .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock