Include lowlevellock.h.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_rdlock.S
1 /* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <sysdep.h>
20 #include <lowlevellock.h>
21 #include <lowlevelrwlock.h>
22 #include <pthread-errnos.h>
23 #include <tcb-offsets.h>
24 #include <kernel-features.h>
25 #include "lowlevel-atomic.h"
26
27
28         .text
29
30         .globl  __pthread_rwlock_rdlock
31         .type   __pthread_rwlock_rdlock,@function
32         .align  5
33 __pthread_rwlock_rdlock:
34         mov.l   r12, @-r15
35         mov.l   r9, @-r15
36         mov.l   r8, @-r15
37         sts.l   pr, @-r15
38         mov     r4, r8
39
40         /* Get the lock.  */
41         mov     #0, r3
42         mov     #1, r4
43 #if MUTEX == 0
44         CMPXCHG (r3, @r8, r4, r2)
45 #else
46         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
47 #endif
48         bf      1f
49 2:
50         mov.l   @(WRITER,r8), r0
51         tst     r0, r0
52         bf      14f
53         mov.l   @(WRITERS_QUEUED,r8), r0
54         tst     r0, r0
55         bt      5f
56         mov     #FLAGS, r0
57         mov.b   @(r0,r8), r0
58         tst     r0, r0
59         bt      5f
60 3:
61         mov.l   @(READERS_QUEUED,r8), r0
62         add     #1, r0
63         mov.l   r0, @(READERS_QUEUED,r8)
64         tst     r0, r0
65         bt      4f
66
67         mov.l   @(READERS_WAKEUP,r8), r9
68
69 #if MUTEX == 0
70         DEC (@r8, r2)
71 #else
72         DEC (@(MUTEX,r8), r2)
73 #endif
74         tst     r2, r2
75         bf      10f
76 11:
77 #if __ASSUME_PRIVATE_FUTEX
78         mov     #PSHARED, r0
79         mov.b   @(r0,r8), r5
80         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
81         xor     r0, r5
82         extu.b  r5, r5
83 #else
84         mov     #PSHARED, r0
85         mov.b   @(r0,r8), r5
86         extu.b  r5, r5
87 # if FUTEX_WAIT != 0
88         mov     #FUTEX_WAIT, r0
89         or      r0, r5
90 # endif
91         stc     gbr, r1
92         mov.w   .Lpfoff, r2
93         add     r2, r1
94         mov.l   @r1, r0
95         xor     r0, r5
96 #endif
97         mov     r8, r4
98         add     #READERS_WAKEUP, r4
99         mov     r9, r6
100         mov     #0, r7
101         mov     #SYS_futex, r3
102         extu.b  r3, r3
103         trapa   #0x14
104         SYSCALL_INST_PAD
105
106         /* Reget the lock.  */
107         mov     #0, r3
108         mov     #1, r4
109 #if MUTEX == 0
110         CMPXCHG (r3, @r8, r4, r2)
111 #else
112         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
113 #endif
114         bf      12f
115 13:
116         mov.l   @(READERS_QUEUED,r8), r0
117         add     #-1, r0
118         bra     2b
119          mov.l  r0, @(READERS_QUEUED,r8)
120
121 5:
122         mov     #0, r3
123         mov.l   @(NR_READERS,r8), r0
124         add     #1, r0
125         mov.l   r0, @(NR_READERS,r8)
126         tst     r0, r0
127         bt      8f
128
129 9:
130 #if MUTEX == 0
131         DEC (@r8, r2)
132 #else
133         DEC (@(MUTEX,r8), r2)
134 #endif
135         tst     r2, r2
136         bf      6f
137 7:
138         lds.l   @r15+, pr
139         mov.l   @r15+, r8
140         mov.l   @r15+, r9
141         mov.l   @r15+, r12
142         rts
143          mov    r3, r0
144
145 #if !__ASSUME_PRIVATE_FUTEX
146 .Lpfoff:
147         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
148 #endif
149
150 1:
151         mov     r8, r5
152 #if MUTEX != 0
153         add     #MUTEX, r5
154 #endif
155         mov     #PSHARED, r0
156         mov.b   @(r0,r8), r6
157         extu.b  r6, r6
158         mov.l   .Lwait0, r1
159         bsrf    r1
160          mov    r2, r4
161 .Lwait0b:
162         bra     2b
163          nop
164 14:
165         stc     gbr, r1
166         mov.w   .Ltidoff, r2
167         add     r2, r1
168         mov.l   @r1, r1
169         cmp/eq  r1, r0
170         bf      3b
171         /* Deadlock detected.  */
172         bra     9b
173          mov    #EDEADLK, r3
174
175 .Ltidoff:
176         .word   TID - TLS_PRE_TCB_SIZE
177         
178 6:
179         mov     r8, r4
180 #if MUTEX != 0
181         add     #MUTEX, r4
182 #endif
183         mov     #PSHARED, r0
184         mov.b   @(r0,r8), r5
185         extu.b  r5, r5
186         mov.l   .Lwake0, r1
187         bsrf    r1
188          nop
189 .Lwake0b:
190         bra     7b
191          mov    #0, r3
192
193 8:
194         /* Overflow.  */
195         mov.l   @(NR_READERS,r8), r1
196         add     #-1, r1
197         mov.l   r1, @(NR_READERS,r8)
198         bra     9b
199          mov    #EAGAIN, r3
200
201 4:
202         /* Overflow.  */
203         mov.l   @(READERS_QUEUED,r8), r1
204         add     #-1, r1
205         mov.l   r1, @(READERS_QUEUED,r8)
206         bra     9b
207          mov    #EAGAIN, r3
208
209 10:
210         mov     r8, r4
211 #if MUTEX != 0
212         add     #MUTEX, r4
213 #endif
214         mov     #PSHARED, r0
215         mov.b   @(r0,r8), r5
216         extu.b  r5, r5
217         mov.l   .Lwake1, r1
218         bsrf    r1
219          nop
220 .Lwake1b:
221         bra     11b
222          nop
223
224 12:
225         mov     r8, r5
226 #if MUTEX != 0
227         add     #MUTEX, r5
228 #endif
229         mov     #PSHARED, r0
230         mov.b   @(r0,r8), r6
231         extu.b  r6, r6
232         mov.l   .Lwait1, r1
233         bsrf    r1
234          mov    r2, r4
235 .Lwait1b:
236         bra     13b
237          nop
238
239         .align  2
240 .Lwait0:
241         .long   __lll_lock_wait-.Lwait0b
242 .Lwake0:
243         .long   __lll_unlock_wake-.Lwake0b
244 .Lwait1:
245         .long   __lll_lock_wait-.Lwait1b
246 .Lwake1:
247         .long   __lll_unlock_wake-.Lwake1b
248         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
249
250         .globl  pthread_rwlock_rdlock
251 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
252
253         .globl  __pthread_rwlock_rdlock_internal
254 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock