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