]>
Commit | Line | Data |
---|---|---|
6cf26f41 UD |
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> | |
326132db | 22 | #include <pthread-errnos.h> |
6cf26f41 UD |
23 | |
24 | ||
25 | #define SYS_gettimeofday __NR_gettimeofday | |
26 | #define SYS_futex 240 | |
27 | #define FUTEX_WAIT 0 | |
28 | #define FUTEX_WAKE 1 | |
29 | ||
6cf26f41 UD |
30 | #ifndef UP |
31 | # define LOCK lock | |
32 | #else | |
33 | # define LOCK | |
34 | #endif | |
35 | ||
36 | ||
37 | .text | |
38 | ||
39 | .globl pthread_rwlock_timedwrlock | |
40 | .type pthread_rwlock_timedwrlock,@function | |
41 | .align 16 | |
42 | pthread_rwlock_timedwrlock: | |
43 | pushl %esi | |
44 | pushl %edi | |
45 | pushl %ebx | |
46 | pushl %ebp | |
47 | subl $8, %esp | |
48 | ||
49 | movl 28(%esp), %ebp | |
50 | movl 32(%esp), %edi | |
51 | ||
52 | /* Get the lock. */ | |
71451de2 UD |
53 | movl $1, %edx |
54 | xorl %eax, %eax | |
6cf26f41 UD |
55 | LOCK |
56 | #if MUTEX == 0 | |
71451de2 | 57 | cmpxchgl %edx, (%ebp) |
6cf26f41 | 58 | #else |
71451de2 | 59 | cmpxchgl %edx, MUTEX(%ebp) |
6cf26f41 | 60 | #endif |
3a226d33 | 61 | jnz 1f |
6cf26f41 UD |
62 | |
63 | 2: movl WRITER(%ebp), %eax | |
64 | testl %eax, %eax | |
65 | jne 14f | |
35e148cb | 66 | cmpl $0, NR_READERS(%ebp) |
6cf26f41 UD |
67 | je 5f |
68 | ||
0a37669a UD |
69 | /* Check the value of the timeout parameter. */ |
70 | 3: cmpl $1000000000, 4(%edi) | |
71 | jae 19f | |
72 | ||
ccf1d573 | 73 | addl $1, WRITERS_QUEUED(%ebp) |
6cf26f41 UD |
74 | je 4f |
75 | ||
18a53579 UD |
76 | movl WRITERS_WAKEUP(%ebp), %esi |
77 | ||
6cf26f41 UD |
78 | LOCK |
79 | #if MUTEX == 0 | |
ccf1d573 | 80 | subl $1, (%ebp) |
6cf26f41 | 81 | #else |
ccf1d573 | 82 | subl $1, MUTEX(%ebp) |
6cf26f41 UD |
83 | #endif |
84 | jne 10f | |
85 | ||
86 | /* Get current time. */ | |
87 | 11: movl %esp, %ebx | |
88 | xorl %ecx, %ecx | |
89 | movl $SYS_gettimeofday, %eax | |
90 | ENTER_KERNEL | |
91 | ||
92 | /* Compute relative timeout. */ | |
93 | movl 4(%esp), %eax | |
94 | movl $1000, %edx | |
95 | mul %edx /* Milli seconds to nano seconds. */ | |
96 | movl (%edi), %ecx | |
97 | movl 4(%edi), %edx | |
98 | subl (%esp), %ecx | |
99 | subl %eax, %edx | |
100 | jns 15f | |
101 | addl $1000000000, %edx | |
ccf1d573 | 102 | subl $1, %ecx |
6cf26f41 UD |
103 | 15: testl %ecx, %ecx |
104 | js 16f /* Time is already up. */ | |
105 | ||
106 | /* Futex call. */ | |
107 | movl %ecx, (%esp) /* Store relative timeout. */ | |
108 | movl %edx, 4(%esp) | |
18a53579 | 109 | movl %esi, %edx |
6cf26f41 UD |
110 | xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */ |
111 | movl %esp, %esi | |
6cf26f41 UD |
112 | leal WRITERS_WAKEUP(%ebp), %ebx |
113 | movl $SYS_futex, %eax | |
114 | ENTER_KERNEL | |
71451de2 | 115 | movl %eax, %ecx |
6cf26f41 UD |
116 | 17: |
117 | ||
118 | /* Reget the lock. */ | |
71451de2 UD |
119 | movl $1, %edx |
120 | xorl %eax, %eax | |
6cf26f41 UD |
121 | LOCK |
122 | #if MUTEX == 0 | |
71451de2 | 123 | cmpxchgl %edx, (%ebp) |
6cf26f41 | 124 | #else |
71451de2 | 125 | cmpxchgl %edx, MUTEX(%ebp) |
6cf26f41 | 126 | #endif |
3a226d33 | 127 | jnz 12f |
6cf26f41 | 128 | |
ccf1d573 | 129 | 13: subl $1, WRITERS_QUEUED(%ebp) |
71451de2 | 130 | cmpl $-ETIMEDOUT, %ecx |
18a53579 UD |
131 | jne 2b |
132 | ||
133 | 18: movl $ETIMEDOUT, %ecx | |
134 | jmp 9f | |
6cf26f41 UD |
135 | |
136 | ||
137 | 5: xorl %ecx, %ecx | |
4ad0bbf4 | 138 | movl %gs:TID, %eax |
6cf26f41 UD |
139 | movl %eax, WRITER(%ebp) |
140 | 9: LOCK | |
141 | #if MUTEX == 0 | |
ccf1d573 | 142 | subl $1, (%ebp) |
6cf26f41 | 143 | #else |
ccf1d573 | 144 | subl $1, MUTEX(%ebp) |
6cf26f41 UD |
145 | #endif |
146 | jne 6f | |
147 | ||
148 | 7: movl %ecx, %eax | |
149 | ||
150 | addl $8, %esp | |
151 | popl %ebp | |
152 | popl %ebx | |
153 | popl %edi | |
154 | popl %esi | |
155 | ret | |
156 | ||
18a53579 UD |
157 | 1: |
158 | #if MUTEX == 0 | |
159 | movl %ebp, %ecx | |
160 | #else | |
161 | leal MUTEX(%ebp), %ecx | |
162 | #endif | |
6cf26f41 UD |
163 | call __lll_mutex_lock_wait |
164 | jmp 2b | |
165 | ||
4ad0bbf4 | 166 | 14: cmpl %gs:TID, %eax |
6cf26f41 | 167 | jne 3b |
0a37669a | 168 | 20: movl $EDEADLK, %ecx |
6cf26f41 UD |
169 | jmp 9b |
170 | ||
18a53579 UD |
171 | 6: |
172 | #if MUTEX == 0 | |
173 | movl %ebp, %eax | |
174 | #else | |
175 | leal MUTEX(%ebp), %eax | |
176 | #endif | |
6cf26f41 UD |
177 | call __lll_mutex_unlock_wake |
178 | jmp 7b | |
179 | ||
180 | /* Overflow. */ | |
ccf1d573 | 181 | 4: subl $1, WRITERS_QUEUED(%ebp) |
6cf26f41 UD |
182 | movl $EAGAIN, %ecx |
183 | jmp 9b | |
184 | ||
18a53579 UD |
185 | 10: |
186 | #if MUTEX == 0 | |
187 | movl %ebp, %eax | |
188 | #else | |
189 | leal MUTEX(%ebp), %eax | |
190 | #endif | |
6cf26f41 UD |
191 | call __lll_mutex_unlock_wake |
192 | jmp 11b | |
193 | ||
18a53579 UD |
194 | 12: |
195 | #if MUTEX == 0 | |
196 | movl %ebp, %ecx | |
197 | #else | |
198 | leal MUTEX(%ebp), %ecx | |
199 | #endif | |
6cf26f41 UD |
200 | call __lll_mutex_lock_wait |
201 | jmp 13b | |
202 | ||
71451de2 | 203 | 16: movl $-ETIMEDOUT, %ecx |
6cf26f41 UD |
204 | jmp 17b |
205 | ||
0a37669a UD |
206 | 19: movl $EINVAL, %ecx |
207 | jmp 9b | |
6cf26f41 | 208 | .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock |