]>
Commit | Line | Data |
---|---|---|
50f1dec5 | 1 | /* Copyright (C) 2002, 2003, 2007 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 | |
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_futex 240 | |
26 | #define FUTEX_WAIT 0 | |
27 | #define FUTEX_WAKE 1 | |
28 | ||
6cf26f41 UD |
29 | #ifndef UP |
30 | # define LOCK lock | |
31 | #else | |
32 | # define LOCK | |
33 | #endif | |
34 | ||
35 | ||
36 | .text | |
37 | ||
38 | .globl __pthread_rwlock_wrlock | |
39 | .type __pthread_rwlock_wrlock,@function | |
40 | .align 16 | |
41 | __pthread_rwlock_wrlock: | |
42 | pushl %esi | |
43 | pushl %ebx | |
44 | ||
45 | xorl %esi, %esi | |
6cf26f41 UD |
46 | movl 12(%esp), %ebx |
47 | ||
48 | /* Get the lock. */ | |
71451de2 UD |
49 | movl $1, %edx |
50 | xorl %eax, %eax | |
6cf26f41 UD |
51 | LOCK |
52 | #if MUTEX == 0 | |
71451de2 | 53 | cmpxchgl %edx, (%ebx) |
6cf26f41 | 54 | #else |
71451de2 | 55 | cmpxchgl %edx, MUTEX(%ebx) |
6cf26f41 | 56 | #endif |
3a226d33 | 57 | jnz 1f |
6cf26f41 UD |
58 | |
59 | 2: movl WRITER(%ebx), %eax | |
60 | testl %eax, %eax | |
61 | jne 14f | |
35e148cb | 62 | cmpl $0, NR_READERS(%ebx) |
6cf26f41 UD |
63 | je 5f |
64 | ||
ccf1d573 | 65 | 3: addl $1, WRITERS_QUEUED(%ebx) |
6cf26f41 UD |
66 | je 4f |
67 | ||
18a53579 UD |
68 | movl WRITERS_WAKEUP(%ebx), %edx |
69 | ||
6cf26f41 UD |
70 | LOCK |
71 | #if MUTEX == 0 | |
ccf1d573 | 72 | subl $1, (%ebx) |
6cf26f41 | 73 | #else |
ccf1d573 | 74 | subl $1, MUTEX(%ebx) |
6cf26f41 UD |
75 | #endif |
76 | jne 10f | |
77 | ||
50f1dec5 UD |
78 | 11: |
79 | #if __ASSUME_PRIVATE_FUTEX | |
991fa82b UD |
80 | movzbl PSHARED(%ebx), %ecx |
81 | xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx | |
50f1dec5 | 82 | #else |
991fa82b UD |
83 | movzbl PSHARED(%ebx), %ecx |
84 | # if FUTEX_WAIT != 0 | |
85 | orl $FUTEX_WAIT, %ecx | |
50f1dec5 UD |
86 | # endif |
87 | xorl %gs:PRIVATE_FUTEX, %ecx | |
88 | #endif | |
89 | addl $WRITERS_WAKEUP, %ebx | |
6cf26f41 UD |
90 | movl $SYS_futex, %eax |
91 | ENTER_KERNEL | |
92 | ||
46a32546 | 93 | subl $WRITERS_WAKEUP, %ebx |
6cf26f41 UD |
94 | |
95 | /* Reget the lock. */ | |
71451de2 UD |
96 | movl $1, %edx |
97 | xorl %eax, %eax | |
6cf26f41 UD |
98 | LOCK |
99 | #if MUTEX == 0 | |
71451de2 | 100 | cmpxchgl %edx, (%ebx) |
6cf26f41 | 101 | #else |
71451de2 | 102 | cmpxchgl %edx, MUTEX(%ebx) |
6cf26f41 | 103 | #endif |
3a226d33 | 104 | jnz 12f |
6cf26f41 | 105 | |
ccf1d573 | 106 | 13: subl $1, WRITERS_QUEUED(%ebx) |
6cf26f41 UD |
107 | jmp 2b |
108 | ||
109 | 5: xorl %ecx, %ecx | |
4ad0bbf4 | 110 | movl %gs:TID, %eax |
6cf26f41 UD |
111 | movl %eax, WRITER(%ebx) |
112 | 9: LOCK | |
113 | #if MUTEX == 0 | |
ccf1d573 | 114 | subl $1, (%ebx) |
6cf26f41 | 115 | #else |
ccf1d573 | 116 | subl $1, MUTEX(%ebx) |
6cf26f41 UD |
117 | #endif |
118 | jne 6f | |
119 | 7: | |
120 | ||
121 | movl %ecx, %eax | |
122 | popl %ebx | |
123 | popl %esi | |
124 | ret | |
125 | ||
18a53579 UD |
126 | 1: |
127 | #if MUTEX == 0 | |
128 | movl %ebx, %ecx | |
129 | #else | |
130 | leal MUTEX(%ebx), %ecx | |
131 | #endif | |
6cf26f41 UD |
132 | call __lll_mutex_lock_wait |
133 | jmp 2b | |
134 | ||
4ad0bbf4 | 135 | 14: cmpl %gs:TID , %eax |
6cf26f41 UD |
136 | jne 3b |
137 | movl $EDEADLK, %ecx | |
138 | jmp 9b | |
139 | ||
18a53579 UD |
140 | 6: |
141 | #if MUTEX == 0 | |
142 | movl %ebx, %eax | |
143 | #else | |
144 | leal MUTEX(%ebx), %eax | |
145 | #endif | |
6cf26f41 UD |
146 | call __lll_mutex_unlock_wake |
147 | jmp 7b | |
148 | ||
ccf1d573 | 149 | 4: subl $1, WRITERS_QUEUED(%ebx) |
6cf26f41 UD |
150 | movl $EAGAIN, %ecx |
151 | jmp 9b | |
152 | ||
18a53579 UD |
153 | 10: |
154 | #if MUTEX == 0 | |
155 | movl %ebx, %eax | |
156 | #else | |
157 | leal MUTEX(%ebx), %eax | |
158 | #endif | |
6cf26f41 UD |
159 | call __lll_mutex_unlock_wake |
160 | jmp 11b | |
161 | ||
18a53579 UD |
162 | 12: |
163 | #if MUTEX == 0 | |
164 | movl %ebx, %ecx | |
165 | #else | |
166 | leal MUTEX(%ebx), %ecx | |
167 | #endif | |
6cf26f41 UD |
168 | call __lll_mutex_lock_wait |
169 | jmp 13b | |
170 | .size __pthread_rwlock_wrlock,.-__pthread_rwlock_wrlock | |
171 | ||
172 | .globl pthread_rwlock_wrlock | |
173 | pthread_rwlock_wrlock = __pthread_rwlock_wrlock | |
174 | ||
175 | .globl __pthread_rwlock_wrlock_internal | |
176 | __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock |