Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_rdlock.S
blob34790fd3b872212195f0bdcd38d2c263b48e9c16
1 /* Copyright (C) 2003-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
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.
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.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
18 #include <sysdep.h>
19 #include <lowlevellock.h>
20 #include <lowlevelrwlock.h>
21 #include <pthread-errnos.h>
22 #include <tcb-offsets.h>
23 #include <kernel-features.h>
24 #include "lowlevel-atomic.h"
27         .text
29         .globl  __pthread_rwlock_rdlock
30         .type   __pthread_rwlock_rdlock,@function
31         .align  5
32         cfi_startproc
33 __pthread_rwlock_rdlock:
34         mov.l   r12, @-r15
35         cfi_adjust_cfa_offset (4)
36         cfi_rel_offset (r12, 0)
37         mov.l   r9, @-r15
38         cfi_adjust_cfa_offset (4)
39         cfi_rel_offset (r9, 0)
40         mov.l   r8, @-r15
41         cfi_adjust_cfa_offset (4)
42         cfi_rel_offset (r8, 0)
43         sts.l   pr, @-r15
44         cfi_adjust_cfa_offset (4)
45         cfi_rel_offset (pr, 0)
46         mov     r4, r8
48         /* Get the lock.  */
49         mov     #0, r3
50         mov     #1, r4
51 #if MUTEX == 0
52         CMPXCHG (r3, @r8, r4, r2)
53 #else
54         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
55 #endif
56         bf      1f
58         mov.l   @(WRITER,r8), r0
59         tst     r0, r0
60         bf      14f
61         mov.l   @(WRITERS_QUEUED,r8), r0
62         tst     r0, r0
63         bt      5f
64         mov     #FLAGS, r0
65         mov.b   @(r0,r8), r0
66         tst     r0, r0
67         bt      5f
69         mov.l   @(READERS_QUEUED,r8), r0
70         add     #1, r0
71         mov.l   r0, @(READERS_QUEUED,r8)
72         tst     r0, r0
73         bt      4f
75         mov.l   @(READERS_WAKEUP,r8), r9
77 #if MUTEX == 0
78         DEC (@r8, r2)
79 #else
80         DEC (@(MUTEX,r8), r2)
81 #endif
82         tst     r2, r2
83         bf      10f
84 11:
85 #ifdef __ASSUME_PRIVATE_FUTEX
86         mov     #PSHARED, r0
87         mov.b   @(r0,r8), r5
88         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
89         xor     r0, r5
90         extu.b  r5, r5
91 #else
92         mov     #PSHARED, r0
93         mov.b   @(r0,r8), r5
94         extu.b  r5, r5
95 # if FUTEX_WAIT != 0
96         mov     #FUTEX_WAIT, r0
97         or      r0, r5
98 # endif
99         stc     gbr, r1
100         mov.w   .Lpfoff, r2
101         add     r2, r1
102         mov.l   @r1, r0
103         xor     r0, r5
104 #endif
105         mov     r8, r4
106         add     #READERS_WAKEUP, r4
107         mov     r9, r6
108         mov     #0, r7
109         mov     #SYS_futex, r3
110         extu.b  r3, r3
111         trapa   #0x14
112         SYSCALL_INST_PAD
114         /* Reget the lock.  */
115         mov     #0, r3
116         mov     #1, r4
117 #if MUTEX == 0
118         CMPXCHG (r3, @r8, r4, r2)
119 #else
120         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
121 #endif
122         bf      12f
124         mov.l   @(READERS_QUEUED,r8), r0
125         add     #-1, r0
126         bra     2b
127          mov.l  r0, @(READERS_QUEUED,r8)
130         mov     #0, r3
131         mov.l   @(NR_READERS,r8), r0
132         add     #1, r0
133         mov.l   r0, @(NR_READERS,r8)
134         tst     r0, r0
135         bt      8f
138 #if MUTEX == 0
139         DEC (@r8, r2)
140 #else
141         DEC (@(MUTEX,r8), r2)
142 #endif
143         tst     r2, r2
144         bf      6f
146         cfi_remember_state
147         lds.l   @r15+, pr
148         cfi_adjust_cfa_offset (-4)
149         cfi_restore (pr)
150         mov.l   @r15+, r8
151         cfi_adjust_cfa_offset (-4)
152         cfi_restore (r8)
153         mov.l   @r15+, r9
154         cfi_adjust_cfa_offset (-4)
155         cfi_restore (r9)
156         mov.l   @r15+, r12
157         cfi_adjust_cfa_offset (-4)
158         cfi_restore (r12)
159         rts
160          mov    r3, r0
161         cfi_restore_state
163 #ifndef __ASSUME_PRIVATE_FUTEX
164 .Lpfoff:
165         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
166 #endif
169         mov     r8, r5
170 #if MUTEX != 0
171         add     #MUTEX, r5
172 #endif
173         mov     #PSHARED, r0
174         mov.b   @(r0,r8), r6
175         extu.b  r6, r6
176         mov.l   .Lwait0, r1
177         bsrf    r1
178          mov    r2, r4
179 .Lwait0b:
180         bra     2b
181          nop
183         stc     gbr, r1
184         mov.w   .Ltidoff, r2
185         add     r2, r1
186         mov.l   @r1, r1
187         cmp/eq  r1, r0
188         bf      3b
189         /* Deadlock detected.  */
190         bra     9b
191          mov    #EDEADLK, r3
193 .Ltidoff:
194         .word   TID - TLS_PRE_TCB_SIZE
197         mov     r8, r4
198 #if MUTEX != 0
199         add     #MUTEX, r4
200 #endif
201         mov     #PSHARED, r0
202         mov.b   @(r0,r8), r5
203         extu.b  r5, r5
204         mov.l   .Lwake0, r1
205         bsrf    r1
206          nop
207 .Lwake0b:
208         bra     7b
209          mov    #0, r3
212         /* Overflow.  */
213         mov.l   @(NR_READERS,r8), r1
214         add     #-1, r1
215         mov.l   r1, @(NR_READERS,r8)
216         bra     9b
217          mov    #EAGAIN, r3
220         /* Overflow.  */
221         mov.l   @(READERS_QUEUED,r8), r1
222         add     #-1, r1
223         mov.l   r1, @(READERS_QUEUED,r8)
224         bra     9b
225          mov    #EAGAIN, r3
228         mov     r8, r4
229 #if MUTEX != 0
230         add     #MUTEX, r4
231 #endif
232         mov     #PSHARED, r0
233         mov.b   @(r0,r8), r5
234         extu.b  r5, r5
235         mov.l   .Lwake1, r1
236         bsrf    r1
237          nop
238 .Lwake1b:
239         bra     11b
240          nop
243         mov     r8, r5
244 #if MUTEX != 0
245         add     #MUTEX, r5
246 #endif
247         mov     #PSHARED, r0
248         mov.b   @(r0,r8), r6
249         extu.b  r6, r6
250         mov.l   .Lwait1, r1
251         bsrf    r1
252          mov    r2, r4
253 .Lwait1b:
254         bra     13b
255          nop
256         cfi_endproc
258         .align  2
259 .Lwait0:
260         .long   __lll_lock_wait-.Lwait0b
261 .Lwake0:
262         .long   __lll_unlock_wake-.Lwake0b
263 .Lwait1:
264         .long   __lll_lock_wait-.Lwait1b
265 .Lwake1:
266         .long   __lll_unlock_wake-.Lwake1b
267         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
269 strong_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock)
270 hidden_def (__pthread_rwlock_rdlock)