OSDN Git Service

21e05e1927ca87e01a58bb9e846b8408258c2db3
[uclinux-h8/uClibc.git] / libpthread / 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 <bits/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         .protected      __pthread_rwlock_rdlock
33         .align  5
34 __pthread_rwlock_rdlock:
35         mov.l   r12, @-r15
36         mov.l   r9, @-r15
37         mov.l   r8, @-r15
38         sts.l   pr, @-r15
39         mov     r4, r8
40
41         /* Get the lock.  */
42         mov     #0, r3
43         mov     #1, r4
44 #if MUTEX == 0
45         CMPXCHG (r3, @r8, r4, r2)
46 #else
47         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
48 #endif
49         bf      1f
50 2:
51         mov.l   @(WRITER,r8), r0
52         tst     r0, r0
53         bf      14f
54         mov.l   @(WRITERS_QUEUED,r8), r0
55         tst     r0, r0
56         bt      5f
57         mov     #FLAGS, r0
58         mov.b   @(r0,r8), r0
59         tst     r0, r0
60         bt      5f
61 3:
62         mov.l   @(READERS_QUEUED,r8), r0
63         add     #1, r0
64         mov.l   r0, @(READERS_QUEUED,r8)
65         tst     r0, r0
66         bt      4f
67
68         mov.l   @(READERS_WAKEUP,r8), r9
69
70 #if MUTEX == 0
71         DEC (@r8, r2)
72 #else
73         DEC (@(MUTEX,r8), r2)
74 #endif
75         tst     r2, r2
76         bf      10f
77 11:
78 #ifdef __ASSUME_PRIVATE_FUTEX
79         mov     #PSHARED, r0
80         mov.b   @(r0,r8), r5
81         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
82         xor     r0, r5
83         extu.b  r5, r5
84 #else
85         mov     #PSHARED, r0
86         mov.b   @(r0,r8), r5
87         extu.b  r5, r5
88 # if FUTEX_WAIT != 0
89         mov     #FUTEX_WAIT, r0
90         or      r0, r5
91 # endif
92         stc     gbr, r1
93         mov.w   .Lpfoff, r2
94         add     r2, r1
95         mov.l   @r1, r0
96         xor     r0, r5
97 #endif
98         mov     r8, r4
99         add     #READERS_WAKEUP, r4
100         mov     r9, r6
101         mov     #0, r7
102         mov     #SYS_futex, r3
103         extu.b  r3, r3
104         trapa   #0x14
105         SYSCALL_INST_PAD
106
107         /* Reget the lock.  */
108         mov     #0, r3
109         mov     #1, r4
110 #if MUTEX == 0
111         CMPXCHG (r3, @r8, r4, r2)
112 #else
113         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
114 #endif
115         bf      12f
116 13:
117         mov.l   @(READERS_QUEUED,r8), r0
118         add     #-1, r0
119         bra     2b
120          mov.l  r0, @(READERS_QUEUED,r8)
121
122 5:
123         mov     #0, r3
124         mov.l   @(NR_READERS,r8), r0
125         add     #1, r0
126         mov.l   r0, @(NR_READERS,r8)
127         tst     r0, r0
128         bt      8f
129
130 9:
131 #if MUTEX == 0
132         DEC (@r8, r2)
133 #else
134         DEC (@(MUTEX,r8), r2)
135 #endif
136         tst     r2, r2
137         bf      6f
138 7:
139         lds.l   @r15+, pr
140         mov.l   @r15+, r8
141         mov.l   @r15+, r9
142         mov.l   @r15+, r12
143         rts
144          mov    r3, r0
145
146 #ifndef __ASSUME_PRIVATE_FUTEX
147 .Lpfoff:
148         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
149 #endif
150
151 1:
152         mov     r8, r5
153 #if MUTEX != 0
154         add     #MUTEX, r5
155 #endif
156         mov     #PSHARED, r0
157         mov.b   @(r0,r8), r6
158         extu.b  r6, r6
159         mov.l   .Lwait0, r1
160         bsrf    r1
161          mov    r2, r4
162 .Lwait0b:
163         bra     2b
164          nop
165 14:
166         stc     gbr, r1
167         mov.w   .Ltidoff, r2
168         add     r2, r1
169         mov.l   @r1, r1
170         cmp/eq  r1, r0
171         bf      3b
172         /* Deadlock detected.  */
173         bra     9b
174          mov    #EDEADLK, r3
175
176 .Ltidoff:
177         .word   TID - TLS_PRE_TCB_SIZE
178
179 6:
180         mov     r8, r4
181 #if MUTEX != 0
182         add     #MUTEX, r4
183 #endif
184         mov     #PSHARED, r0
185         mov.b   @(r0,r8), r5
186         extu.b  r5, r5
187         mov.l   .Lwake0, r1
188         bsrf    r1
189          nop
190 .Lwake0b:
191         bra     7b
192          mov    #0, r3
193
194 8:
195         /* Overflow.  */
196         mov.l   @(NR_READERS,r8), r1
197         add     #-1, r1
198         mov.l   r1, @(NR_READERS,r8)
199         bra     9b
200          mov    #EAGAIN, r3
201
202 4:
203         /* Overflow.  */
204         mov.l   @(READERS_QUEUED,r8), r1
205         add     #-1, r1
206         mov.l   r1, @(READERS_QUEUED,r8)
207         bra     9b
208          mov    #EAGAIN, r3
209
210 10:
211         mov     r8, r4
212 #if MUTEX != 0
213         add     #MUTEX, r4
214 #endif
215         mov     #PSHARED, r0
216         mov.b   @(r0,r8), r5
217         extu.b  r5, r5
218         mov.l   .Lwake1, r1
219         bsrf    r1
220          nop
221 .Lwake1b:
222         bra     11b
223          nop
224
225 12:
226         mov     r8, r5
227 #if MUTEX != 0
228         add     #MUTEX, r5
229 #endif
230         mov     #PSHARED, r0
231         mov.b   @(r0,r8), r6
232         extu.b  r6, r6
233         mov.l   .Lwait1, r1
234         bsrf    r1
235          mov    r2, r4
236 .Lwait1b:
237         bra     13b
238          nop
239
240         .align  2
241 .Lwait0:
242         .long   __lll_lock_wait-.Lwait0b
243 .Lwake0:
244         .long   __lll_unlock_wake-.Lwake0b
245 .Lwait1:
246         .long   __lll_lock_wait-.Lwait1b
247 .Lwake1:
248         .long   __lll_unlock_wake-.Lwake1b
249         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
250
251         .globl  pthread_rwlock_rdlock
252 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
253
254         .globl  __pthread_rwlock_rdlock_internal
255 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock