]>
Commit | Line | Data |
---|---|---|
d4697bc9 | 1 | /* Copyright (C) 2002-2014 Free Software Foundation, Inc. |
6cf26f41 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/>. */ | |
6cf26f41 UD |
18 | |
19 | #include <sysdep.h> | |
e51deae7 | 20 | #include <lowlevellock.h> |
6cf26f41 | 21 | #include <lowlevelrwlock.h> |
326132db | 22 | #include <pthread-errnos.h> |
f8de5057 | 23 | #include <kernel-features.h> |
6cf26f41 UD |
24 | |
25 | ||
6cf26f41 UD |
26 | .text |
27 | ||
28 | .globl pthread_rwlock_timedrdlock | |
29 | .type pthread_rwlock_timedrdlock,@function | |
30 | .align 16 | |
31 | pthread_rwlock_timedrdlock: | |
62605cbf | 32 | cfi_startproc |
6cf26f41 | 33 | pushl %esi |
62605cbf | 34 | cfi_adjust_cfa_offset(4) |
6cf26f41 | 35 | pushl %edi |
62605cbf | 36 | cfi_adjust_cfa_offset(4) |
6cf26f41 | 37 | pushl %ebx |
62605cbf | 38 | cfi_adjust_cfa_offset(4) |
6cf26f41 | 39 | pushl %ebp |
62605cbf UD |
40 | cfi_adjust_cfa_offset(4) |
41 | cfi_offset(%esi, -8) | |
42 | cfi_offset(%edi, -12) | |
43 | cfi_offset(%ebx, -16) | |
44 | cfi_offset(%ebp, -20) | |
6cf26f41 | 45 | subl $8, %esp |
62605cbf | 46 | cfi_adjust_cfa_offset(8) |
6cf26f41 UD |
47 | |
48 | movl 28(%esp), %ebp | |
49 | movl 32(%esp), %edi | |
50 | ||
51 | /* Get the lock. */ | |
71451de2 UD |
52 | movl $1, %edx |
53 | xorl %eax, %eax | |
6cf26f41 UD |
54 | LOCK |
55 | #if MUTEX == 0 | |
71451de2 | 56 | cmpxchgl %edx, (%ebp) |
6cf26f41 | 57 | #else |
71451de2 | 58 | cmpxchgl %edx, MUTEX(%ebp) |
6cf26f41 | 59 | #endif |
3a226d33 | 60 | jnz 1f |
6cf26f41 UD |
61 | |
62 | 2: movl WRITER(%ebp), %eax | |
63 | testl %eax, %eax | |
64 | jne 14f | |
35e148cb | 65 | cmpl $0, WRITERS_QUEUED(%ebp) |
6cf26f41 | 66 | je 5f |
991fa82b | 67 | cmpb $0, FLAGS(%ebp) |
6cf26f41 UD |
68 | je 5f |
69 | ||
0a37669a UD |
70 | /* Check the value of the timeout parameter. */ |
71 | 3: cmpl $1000000000, 4(%edi) | |
72 | jae 19f | |
73 | ||
ccf1d573 | 74 | addl $1, READERS_QUEUED(%ebp) |
6cf26f41 UD |
75 | je 4f |
76 | ||
18a53579 UD |
77 | movl READERS_WAKEUP(%ebp), %esi |
78 | ||
6cf26f41 UD |
79 | LOCK |
80 | #if MUTEX == 0 | |
ccf1d573 | 81 | subl $1, (%ebp) |
6cf26f41 | 82 | #else |
ccf1d573 | 83 | subl $1, MUTEX(%ebp) |
6cf26f41 UD |
84 | #endif |
85 | jne 10f | |
86 | ||
87 | /* Get current time. */ | |
88 | 11: movl %esp, %ebx | |
89 | xorl %ecx, %ecx | |
e51deae7 | 90 | movl $__NR_gettimeofday, %eax |
6cf26f41 UD |
91 | ENTER_KERNEL |
92 | ||
93 | /* Compute relative timeout. */ | |
94 | movl 4(%esp), %eax | |
95 | movl $1000, %edx | |
96 | mul %edx /* Milli seconds to nano seconds. */ | |
97 | movl (%edi), %ecx | |
98 | movl 4(%edi), %edx | |
99 | subl (%esp), %ecx | |
100 | subl %eax, %edx | |
101 | jns 15f | |
102 | addl $1000000000, %edx | |
ccf1d573 | 103 | subl $1, %ecx |
6cf26f41 UD |
104 | 15: testl %ecx, %ecx |
105 | js 16f /* Time is already up. */ | |
106 | ||
107 | /* Futex call. */ | |
108 | movl %ecx, (%esp) /* Store relative timeout. */ | |
109 | movl %edx, 4(%esp) | |
50f1dec5 | 110 | |
18a53579 | 111 | movl %esi, %edx |
22502ea2 | 112 | #ifdef __ASSUME_PRIVATE_FUTEX |
991fa82b UD |
113 | movzbl PSHARED(%ebp), %ecx |
114 | xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx | |
50f1dec5 | 115 | #else |
991fa82b UD |
116 | movzbl PSHARED(%ebp), %ecx |
117 | # if FUTEX_WAIT != 0 | |
118 | orl $FUTEX_WAIT, %ecx | |
50f1dec5 UD |
119 | # endif |
120 | xorl %gs:PRIVATE_FUTEX, %ecx | |
121 | #endif | |
6cf26f41 | 122 | movl %esp, %esi |
6cf26f41 UD |
123 | leal READERS_WAKEUP(%ebp), %ebx |
124 | movl $SYS_futex, %eax | |
125 | ENTER_KERNEL | |
6f59d56e | 126 | movl %eax, %esi |
6cf26f41 UD |
127 | 17: |
128 | ||
129 | /* Reget the lock. */ | |
71451de2 UD |
130 | movl $1, %edx |
131 | xorl %eax, %eax | |
6cf26f41 UD |
132 | LOCK |
133 | #if MUTEX == 0 | |
71451de2 | 134 | cmpxchgl %edx, (%ebp) |
6cf26f41 | 135 | #else |
71451de2 | 136 | cmpxchgl %edx, MUTEX(%ebp) |
6cf26f41 | 137 | #endif |
3a226d33 | 138 | jnz 12f |
6cf26f41 | 139 | |
ccf1d573 | 140 | 13: subl $1, READERS_QUEUED(%ebp) |
6f59d56e | 141 | cmpl $-ETIMEDOUT, %esi |
6cf26f41 | 142 | jne 2b |
18a53579 | 143 | |
e51deae7 | 144 | 18: movl $ETIMEDOUT, %edx |
18a53579 | 145 | jmp 9f |
6cf26f41 UD |
146 | |
147 | ||
e51deae7 | 148 | 5: xorl %edx, %edx |
ccf1d573 | 149 | addl $1, NR_READERS(%ebp) |
6cf26f41 UD |
150 | je 8f |
151 | 9: LOCK | |
152 | #if MUTEX == 0 | |
ccf1d573 | 153 | subl $1, (%ebp) |
6cf26f41 | 154 | #else |
ccf1d573 | 155 | subl $1, MUTEX(%ebp) |
6cf26f41 UD |
156 | #endif |
157 | jne 6f | |
158 | ||
e51deae7 | 159 | 7: movl %edx, %eax |
6cf26f41 UD |
160 | |
161 | addl $8, %esp | |
62605cbf | 162 | cfi_adjust_cfa_offset(-8) |
6cf26f41 | 163 | popl %ebp |
62605cbf UD |
164 | cfi_adjust_cfa_offset(-4) |
165 | cfi_restore(%ebp) | |
6cf26f41 | 166 | popl %ebx |
62605cbf UD |
167 | cfi_adjust_cfa_offset(-4) |
168 | cfi_restore(%ebx) | |
6cf26f41 | 169 | popl %edi |
62605cbf UD |
170 | cfi_adjust_cfa_offset(-4) |
171 | cfi_restore(%edi) | |
6cf26f41 | 172 | popl %esi |
62605cbf UD |
173 | cfi_adjust_cfa_offset(-4) |
174 | cfi_restore(%esi) | |
6cf26f41 UD |
175 | ret |
176 | ||
62605cbf UD |
177 | cfi_adjust_cfa_offset(24) |
178 | cfi_offset(%esi, -8) | |
179 | cfi_offset(%edi, -12) | |
180 | cfi_offset(%ebx, -16) | |
181 | cfi_offset(%ebp, -20) | |
18a53579 UD |
182 | 1: |
183 | #if MUTEX == 0 | |
e51deae7 | 184 | movl %ebp, %edx |
18a53579 | 185 | #else |
e51deae7 | 186 | leal MUTEX(%ebp), %edx |
18a53579 | 187 | #endif |
cdffaaa6 | 188 | movzbl PSHARED(%ebp), %ecx |
e51deae7 | 189 | call __lll_lock_wait |
6cf26f41 UD |
190 | jmp 2b |
191 | ||
4ad0bbf4 | 192 | 14: cmpl %gs:TID, %eax |
6cf26f41 | 193 | jne 3b |
e51deae7 | 194 | movl $EDEADLK, %edx |
6cf26f41 UD |
195 | jmp 9b |
196 | ||
18a53579 UD |
197 | 6: |
198 | #if MUTEX == 0 | |
199 | movl %ebp, %eax | |
200 | #else | |
201 | leal MUTEX(%ebp), %eax | |
202 | #endif | |
cdffaaa6 | 203 | movzbl PSHARED(%ebp), %ecx |
e51deae7 | 204 | call __lll_unlock_wake |
6cf26f41 UD |
205 | jmp 7b |
206 | ||
207 | /* Overflow. */ | |
ccf1d573 | 208 | 8: subl $1, NR_READERS(%ebp) |
e51deae7 | 209 | movl $EAGAIN, %edx |
6cf26f41 UD |
210 | jmp 9b |
211 | ||
212 | /* Overflow. */ | |
ccf1d573 | 213 | 4: subl $1, READERS_QUEUED(%ebp) |
e51deae7 | 214 | movl $EAGAIN, %edx |
6cf26f41 UD |
215 | jmp 9b |
216 | ||
18a53579 UD |
217 | 10: |
218 | #if MUTEX == 0 | |
219 | movl %ebp, %eax | |
220 | #else | |
221 | leal MUTEX(%ebp), %eax | |
222 | #endif | |
cdffaaa6 | 223 | movzbl PSHARED(%ebp), %ecx |
e51deae7 | 224 | call __lll_unlock_wake |
6cf26f41 UD |
225 | jmp 11b |
226 | ||
18a53579 UD |
227 | 12: |
228 | #if MUTEX == 0 | |
e51deae7 | 229 | movl %ebp, %edx |
18a53579 | 230 | #else |
e51deae7 | 231 | leal MUTEX(%ebp), %edx |
18a53579 | 232 | #endif |
cdffaaa6 | 233 | movzbl PSHARED(%ebp), %ecx |
e51deae7 | 234 | call __lll_lock_wait |
6cf26f41 UD |
235 | jmp 13b |
236 | ||
6f59d56e | 237 | 16: movl $-ETIMEDOUT, %esi |
6cf26f41 UD |
238 | jmp 17b |
239 | ||
e51deae7 | 240 | 19: movl $EINVAL, %edx |
0a37669a | 241 | jmp 9b |
62605cbf | 242 | cfi_endproc |
6cf26f41 | 243 | .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock |