]>
Commit | Line | Data |
---|---|---|
da49194d 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> |
da49194d UD |
23 | |
24 | ||
25 | #define SYS_futex 202 | |
26 | #define FUTEX_WAIT 0 | |
27 | #define FUTEX_WAKE 1 | |
28 | ||
da49194d UD |
29 | #ifndef UP |
30 | # define LOCK lock | |
31 | #else | |
32 | # define LOCK | |
33 | #endif | |
34 | ||
35 | ||
36 | .text | |
37 | ||
38 | .globl __pthread_rwlock_rdlock | |
39 | .type __pthread_rwlock_rdlock,@function | |
40 | .align 16 | |
41 | __pthread_rwlock_rdlock: | |
42 | xorq %r10, %r10 | |
43 | ||
44 | /* Get the lock. */ | |
45 | movl $1, %esi | |
3a226d33 | 46 | xorl %eax, %eax |
da49194d UD |
47 | LOCK |
48 | #if MUTEX == 0 | |
3a226d33 | 49 | cmpxchgl %esi, (%rdi) |
da49194d | 50 | #else |
3a226d33 | 51 | cmpxchgl %esi, MUTEX(%rdi) |
da49194d | 52 | #endif |
3a226d33 | 53 | jnz 1f |
da49194d | 54 | |
4ad0bbf4 UD |
55 | 2: movl WRITER(%rdi), %eax |
56 | testl %eax, %eax | |
da49194d UD |
57 | jne 14f |
58 | cmpl $0, WRITERS_QUEUED(%rdi) | |
59 | je 5f | |
60 | cmpl $0, FLAGS(%rdi) | |
61 | je 5f | |
62 | ||
63 | 3: incl READERS_QUEUED(%rdi) | |
64 | je 4f | |
65 | ||
66 | movl READERS_WAKEUP(%rdi), %edx | |
67 | ||
68 | LOCK | |
69 | #if MUTEX == 0 | |
46a32546 | 70 | decl (%rdi) |
da49194d | 71 | #else |
46a32546 | 72 | decl MUTEX(%rdi) |
da49194d UD |
73 | #endif |
74 | jne 10f | |
75 | ||
46a32546 | 76 | 11: addq $READERS_WAKEUP, %rdi |
92ed3daf | 77 | movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ |
da49194d UD |
78 | movq $SYS_futex, %rax |
79 | syscall | |
80 | ||
46a32546 | 81 | subq $READERS_WAKEUP, %rdi |
da49194d UD |
82 | |
83 | /* Reget the lock. */ | |
84 | movl $1, %esi | |
3a226d33 | 85 | xorl %eax, %eax |
da49194d UD |
86 | LOCK |
87 | #if MUTEX == 0 | |
3a226d33 | 88 | cmpxchgl %esi, (%rdi) |
da49194d | 89 | #else |
3a226d33 | 90 | cmpxchgl %esi, MUTEX(%rdi) |
da49194d | 91 | #endif |
3a226d33 | 92 | jnz 12f |
da49194d UD |
93 | |
94 | 13: decl READERS_QUEUED(%rdi) | |
95 | jmp 2b | |
96 | ||
92ed3daf | 97 | 5: xorq %rdx, %rdx |
da49194d UD |
98 | incl NR_READERS(%rdi) |
99 | je 8f | |
100 | 9: LOCK | |
101 | #if MUTEX == 0 | |
102 | decl (%rdi) | |
103 | #else | |
104 | decl MUTEX(%rdi) | |
105 | #endif | |
106 | jne 6f | |
107 | 7: | |
108 | ||
92ed3daf | 109 | movq %rdx, %rax |
da49194d UD |
110 | retq |
111 | ||
112 | 1: | |
113 | #if MUTEX != 0 | |
114 | addq $MUTEX, %rdi | |
115 | #endif | |
92ed3daf | 116 | callq __lll_mutex_lock_wait |
da49194d UD |
117 | #if MUTEX != 0 |
118 | subq $MUTEX, %rdi | |
119 | #endif | |
120 | jmp 2b | |
121 | ||
4ad0bbf4 | 122 | 14: cmpl %fs:TID, %eax |
da49194d UD |
123 | jne 3b |
124 | /* Deadlock detected. */ | |
92ed3daf | 125 | movq $EDEADLK, %rdx |
da49194d UD |
126 | jmp 9b |
127 | ||
128 | 6: | |
129 | #if MUTEX != 0 | |
130 | addq $MUTEX, %rdi | |
131 | #endif | |
92ed3daf | 132 | callq __lll_mutex_unlock_wake |
da49194d UD |
133 | #if MUTEX != 0 |
134 | subq $MUTEX, %rdi | |
135 | #endif | |
136 | jmp 7b | |
137 | ||
138 | /* Overflow. */ | |
139 | 8: decl NR_READERS(%rdi) | |
92ed3daf | 140 | movq $EAGAIN, %rdx |
da49194d UD |
141 | jmp 9b |
142 | ||
143 | /* Overflow. */ | |
144 | 4: decl READERS_QUEUED(%rdi) | |
92ed3daf | 145 | movq $EAGAIN, %rdx |
da49194d UD |
146 | jmp 9b |
147 | ||
148 | 10: | |
149 | #if MUTEX != 0 | |
150 | addq $MUTEX, %rdi | |
151 | #endif | |
92ed3daf | 152 | callq __lll_mutex_unlock_wake |
da49194d UD |
153 | #if MUTEX != 0 |
154 | subq $MUTEX, %rdi | |
155 | #endif | |
156 | jmp 11b | |
157 | ||
158 | 12: | |
159 | #if MUTEX == 0 | |
160 | addq $MUTEX, %rdi | |
161 | #endif | |
92ed3daf | 162 | callq __lll_mutex_lock_wait |
da49194d UD |
163 | #if MUTEX != 0 |
164 | subq $MUTEX, %rdi | |
165 | #endif | |
166 | jmp 13b | |
167 | .size __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock | |
168 | ||
169 | .globl pthread_rwlock_rdlock | |
170 | pthread_rwlock_rdlock = __pthread_rwlock_rdlock | |
171 | ||
172 | .globl __pthread_rwlock_rdlock_internal | |
173 | __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock |