]> sourceware.org Git - glibc.git/blob - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
Update.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_rwlock_timedwrlock.S
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
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
25 #define SYS_futex 202
26 #define FUTEX_WAIT 0
27 #define FUTEX_WAKE 1
28
29 /* For the calculation see asm/vsyscall.h. */
30 #define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
31
32 #ifndef UP
33 # define LOCK lock
34 #else
35 # define LOCK
36 #endif
37
38
39 .text
40
41 .globl pthread_rwlock_timedwrlock
42 .type pthread_rwlock_timedwrlock,@function
43 .align 16
44 pthread_rwlock_timedwrlock:
45 pushq %r12
46 pushq %r13
47 pushq %r14
48 subq $16, %rsp
49
50 movq %rdi, %r12
51 movq %rsi, %r13
52
53 /* Get the lock. */
54 movl $1, %esi
55 xorl %eax, %eax
56 LOCK
57 #if MUTEX == 0
58 cmpxchgl %esi, (%rdi)
59 #else
60 cmpxchgl %esi, MUTEX(%rdi)
61 #endif
62 jnz 1f
63
64 2: movl WRITER(%r12), %eax
65 testl %eax, %eax
66 jne 14f
67 cmpl $0, NR_READERS(%r12)
68 je 5f
69
70 /* Check the value of the timeout parameter. */
71 3: cmpq $1000000000, 8(%r13)
72 jae 19f
73
74 incl WRITERS_QUEUED(%r12)
75 je 4f
76
77 movl WRITERS_WAKEUP(%r12), %r14d
78
79 LOCK
80 #if MUTEX == 0
81 decl (%r12)
82 #else
83 decl MUTEX(%r12)
84 #endif
85 jne 10f
86
87 /* Get current time. */
88 11: movq %rsp, %rdi
89 xorq %rsi, %rsi
90 movq $VSYSCALL_ADDR_vgettimeofday, %rax
91 callq *%rax
92
93 /* Compute relative timeout. */
94 movq 8(%rsp), %rax
95 movq $1000, %rdi
96 mul %rdi /* Milli seconds to nano seconds. */
97 movq (%r13), %rcx
98 movq 8(%r13), %rdi
99 subq (%rsp), %rcx
100 subq %rax, %rdi
101 jns 15f
102 addq $1000000000, %rdi
103 decq %rcx
104 15: testq %rcx, %rcx
105 js 16f /* Time is already up. */
106
107 /* Futex call. */
108 movq %rcx, (%rsp) /* Store relative timeout. */
109 movq %rdi, 8(%rsp)
110
111 xorq %rsi, %rsi /* movq $FUTEX_WAIT, %rsi */
112 movq %rsp, %r10
113 movl %r14d, %edx
114 leaq WRITERS_WAKEUP(%r12), %rdi
115 movq $SYS_futex, %rax
116 syscall
117 movq %rax, %rdx
118 17:
119
120 /* Reget the lock. */
121 movl $1, %esi
122 xorl %eax, %eax
123 LOCK
124 #if MUTEX == 0
125 cmpxchgl %esi, (%r12)
126 #else
127 cmpxchgl %esi, MUTEX(%r12)
128 #endif
129 jnz 12f
130
131 13: decl WRITERS_QUEUED(%r12)
132 cmpq $-ETIMEDOUT, %rdx
133 jne 2b
134
135 18: movq $ETIMEDOUT, %rdx
136 jmp 9f
137
138
139 5: xorq %rdx, %rdx
140 movl %fs:TID, %eax
141 movl %eax, WRITER(%r12)
142 9: LOCK
143 #if MUTEX == 0
144 decl (%r12)
145 #else
146 decl MUTEX(%r12)
147 #endif
148 jne 6f
149
150 7: movq %rdx, %rax
151
152 addq $16, %rsp
153 popq %r14
154 popq %r13
155 popq %r12
156 retq
157
158 1:
159 #if MUTEX != 0
160 addq $MUTEX, %rdi
161 #endif
162 callq __lll_mutex_lock_wait
163 jmp 2b
164
165 14: cmpl %fs:TID, %eax
166 jne 3b
167 20: movq $EDEADLK, %rdx
168 jmp 9b
169
170 6:
171 #if MUTEX == 0
172 movq %r12, %rdi
173 #else
174 leal MUTEX(%r12), %rdi
175 #endif
176 callq __lll_mutex_unlock_wake
177 jmp 7b
178
179 /* Overflow. */
180 4: decl WRITERS_QUEUED(%r12)
181 movq $EAGAIN, %rdx
182 jmp 9b
183
184 10:
185 #if MUTEX == 0
186 movq %r12, %rdi
187 #else
188 leaq MUTEX(%r12), %rdi
189 #endif
190 callq __lll_mutex_unlock_wake
191 jmp 11b
192
193 12:
194 #if MUTEX == 0
195 movq %r12, %rdi
196 #else
197 leaq MUTEX(%r12), %rdi
198 #endif
199 callq __lll_mutex_lock_wait
200 jmp 13b
201
202 16: movq $-ETIMEDOUT, %rdx
203 jmp 17b
204
205 19: movq $EINVAL, %rdx
206 jmp 9b
207 .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock
This page took 0.048603 seconds and 5 git commands to generate.