]>
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> |
f8de5057 | 22 | #include <kernel-features.h> |
6cf26f41 UD |
23 | |
24 | ||
6cf26f41 UD |
25 | .text |
26 | ||
27 | .globl __pthread_rwlock_unlock | |
28 | .type __pthread_rwlock_unlock,@function | |
29 | .align 16 | |
30 | __pthread_rwlock_unlock: | |
62605cbf | 31 | cfi_startproc |
6cf26f41 | 32 | pushl %ebx |
62605cbf | 33 | cfi_adjust_cfa_offset(4) |
6cf26f41 | 34 | pushl %edi |
62605cbf UD |
35 | cfi_adjust_cfa_offset(4) |
36 | cfi_offset(%ebx, -8) | |
37 | cfi_offset(%edi, -12) | |
6cf26f41 | 38 | |
bd8bb78b | 39 | movl 12(%esp), %edi |
6cf26f41 UD |
40 | |
41 | /* Get the lock. */ | |
71451de2 UD |
42 | movl $1, %edx |
43 | xorl %eax, %eax | |
6cf26f41 UD |
44 | LOCK |
45 | #if MUTEX == 0 | |
71451de2 | 46 | cmpxchgl %edx, (%edi) |
6cf26f41 | 47 | #else |
71451de2 | 48 | cmpxchgl %edx, MUTEX(%edi) |
6cf26f41 | 49 | #endif |
3a226d33 | 50 | jnz 1f |
6cf26f41 UD |
51 | |
52 | 2: cmpl $0, WRITER(%edi) | |
53 | jne 5f | |
ccf1d573 | 54 | subl $1, NR_READERS(%edi) |
6cf26f41 UD |
55 | jnz 6f |
56 | ||
57 | 5: movl $0, WRITER(%edi) | |
58 | ||
50f1dec5 | 59 | movl $1, %edx |
18a53579 | 60 | leal WRITERS_WAKEUP(%edi), %ebx |
18a53579 UD |
61 | cmpl $0, WRITERS_QUEUED(%edi) |
62 | jne 0f | |
63 | ||
64 | /* If also no readers waiting nothing to do. */ | |
65 | cmpl $0, READERS_QUEUED(%edi) | |
66 | je 6f | |
67 | ||
68 | movl $0x7fffffff, %edx | |
69 | leal READERS_WAKEUP(%edi), %ebx | |
70 | ||
ccf1d573 | 71 | 0: addl $1, (%ebx) |
d2637c70 UD |
72 | LOCK |
73 | #if MUTEX == 0 | |
ccf1d573 | 74 | subl $1, (%edi) |
d2637c70 | 75 | #else |
ccf1d573 | 76 | subl $1, MUTEX(%edi) |
d2637c70 UD |
77 | #endif |
78 | jne 7f | |
79 | ||
50f1dec5 | 80 | 8: |
22502ea2 | 81 | #ifdef __ASSUME_PRIVATE_FUTEX |
991fa82b UD |
82 | movzbl PSHARED(%edi), %ecx |
83 | xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx | |
50f1dec5 | 84 | #else |
991fa82b UD |
85 | movzbl PSHARED(%edi), %ecx |
86 | orl $FUTEX_WAKE, %ecx | |
50f1dec5 UD |
87 | xorl %gs:PRIVATE_FUTEX, %ecx |
88 | #endif | |
89 | movl $SYS_futex, %eax | |
6cf26f41 UD |
90 | ENTER_KERNEL |
91 | ||
d2637c70 UD |
92 | xorl %eax, %eax |
93 | popl %edi | |
62605cbf UD |
94 | cfi_adjust_cfa_offset(-4) |
95 | cfi_restore(%edi) | |
d2637c70 | 96 | popl %ebx |
62605cbf UD |
97 | cfi_adjust_cfa_offset(-4) |
98 | cfi_restore(%ebx) | |
d2637c70 UD |
99 | ret |
100 | ||
62605cbf UD |
101 | cfi_adjust_cfa_offset(8) |
102 | cfi_offset(%ebx, -8) | |
103 | cfi_offset(%edi, -12) | |
d2637c70 | 104 | .align 16 |
6cf26f41 UD |
105 | 6: LOCK |
106 | #if MUTEX == 0 | |
ccf1d573 | 107 | subl $1, (%edi) |
6cf26f41 | 108 | #else |
ccf1d573 | 109 | subl $1, MUTEX(%edi) |
6cf26f41 UD |
110 | #endif |
111 | jne 3f | |
112 | ||
113 | 4: xorl %eax, %eax | |
114 | popl %edi | |
6cf26f41 UD |
115 | popl %ebx |
116 | ret | |
117 | ||
18a53579 UD |
118 | 1: |
119 | #if MUTEX == 0 | |
e51deae7 | 120 | movl %edi, %edx |
18a53579 | 121 | #else |
e51deae7 | 122 | leal MUTEX(%edi), %edx |
18a53579 | 123 | #endif |
cdffaaa6 | 124 | movzbl PSHARED(%edi), %ecx |
e51deae7 | 125 | call __lll_lock_wait |
6cf26f41 UD |
126 | jmp 2b |
127 | ||
18a53579 UD |
128 | 3: |
129 | #if MUTEX == 0 | |
130 | movl %edi, %eax | |
131 | #else | |
6f59d56e | 132 | leal MUTEX(%edi), %eax |
18a53579 | 133 | #endif |
cdffaaa6 | 134 | movzbl PSHARED(%edi), %ecx |
e51deae7 | 135 | call __lll_unlock_wake |
6cf26f41 UD |
136 | jmp 4b |
137 | ||
d2637c70 UD |
138 | 7: |
139 | #if MUTEX == 0 | |
140 | movl %edi, %eax | |
141 | #else | |
6f59d56e | 142 | leal MUTEX(%edi), %eax |
d2637c70 | 143 | #endif |
cdffaaa6 | 144 | movzbl PSHARED(%edi), %ecx |
e51deae7 | 145 | call __lll_unlock_wake |
d2637c70 | 146 | jmp 8b |
62605cbf | 147 | cfi_endproc |
6cf26f41 UD |
148 | .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock |
149 | ||
4d17e683 AS |
150 | strong_alias (__pthread_rwlock_unlock, pthread_rwlock_unlock) |
151 | hidden_def (__pthread_rwlock_unlock) |