2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_wrlock.S
blob6de65cc64018818eb56b2ada45c2672a4ff8bcbb
1 /* Copyright (C) 2003, 2007 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, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
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"
28         .text
30         .globl  __pthread_rwlock_wrlock
31         .type   __pthread_rwlock_wrlock,@function
32         .align  5
33 __pthread_rwlock_wrlock:
34         mov.l   r12, @-r15
35         mov.l   r9, @-r15
36         mov.l   r8, @-r15
37         sts.l   pr, @-r15
38         mov     r4, r8
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
50         mov.l   @(WRITER,r8), r0
51         tst     r0, r0
52         bf      14f
53         mov.l   @(NR_READERS,r8), r0
54         tst     r0, r0
55         bt      5f
57         mov.l   @(WRITERS_QUEUED,r8), r0
58         add     #1, r0
59         mov.l   r0, @(WRITERS_QUEUED,r8)
60         tst     r0, r0
61         bt      4f
63         mov.l   @(WRITERS_WAKEUP,r8), r9
65 #if MUTEX == 0
66         DEC (@r8, r2)
67 #else
68         DEC (@(MUTEX,r8), r2)
69 #endif
70         tst     r2, r2
71         bf      10f
72 11:
73         mov     r8, r4
74         add     #WRITERS_WAKEUP, r4
75 #ifdef __ASSUME_PRIVATE_FUTEX
76         mov     #PSHARED, r0
77         mov.b   @(r0,r8), r5
78         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
79         xor     r0, r5
80         extu.b  r5, r5
81 #else
82         mov     #PSHARED, r0
83         mov.b   @(r0,r8), r5
84         extu.b  r5, r5
85 # if FUTEX_WAIT != 0
86         mov     #FUTEX_WAIT, r0
87         or      r0, r5
88 # endif
89         stc     gbr, r1
90         mov.w   .Lpfoff, r2
91         add     r2, r1
92         mov.l   @r1, r0
93         xor     r0, r5
94 #endif
95         mov     r9, r6
96         mov     #0, r7
97         mov     #SYS_futex, r3
98         extu.b  r3, r3
99         trapa   #0x14
100         SYSCALL_INST_PAD
102         /* Reget the lock.  */
103         mov     #0, r3
104         mov     #1, r4
105 #if MUTEX == 0
106         CMPXCHG (r3, @r8, r4, r2)
107 #else
108         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
109 #endif
110         bf      12f
112         mov.l   @(WRITERS_QUEUED,r8), r0
113         add     #-1, r0
114         bra     2b
115          mov.l  r0, @(WRITERS_QUEUED,r8)
118         mov     #0, r3
119         stc     gbr, r0
120         mov.w   .Ltidoff, r1
121         mov.l   @(r0,r1), r0
122         mov.l   r0, @(WRITER,r8)
124 #if MUTEX == 0
125         DEC (@r8, r2)
126 #else
127         DEC (@(MUTEX,r8), r2)
128 #endif
129         tst     r2, r2
130         bf      6f
132         lds.l   @r15+, pr
133         mov.l   @r15+, r8
134         mov.l   @r15+, r9
135         mov.l   @r15+, r12
136         rts
137          mov    r3, r0
140         mov     r8, r5
141 #if MUTEX != 0
142         add     #MUTEX, r5
143 #endif
144         mov     #PSHARED, r0
145         mov.b   @(r0,r8), r6
146         extu.b  r6, r6
147         mov.l   .Lwait4, r1
148         bsrf    r1
149          mov    r2, r4
150 .Lwait4b:
151         bra     2b
152          nop
154         stc     gbr, r1
155         mov.w   .Ltidoff, r2
156         add     r2, r1
157         mov.l   @r1, r1
158         cmp/eq  r1, r0
159         bf      3b
160         bra     9b
161          mov    #EDEADLK, r3
163         mov     r8, r4
164 #if MUTEX != 0
165         add     #MUTEX, r4
166 #endif
167         mov     #PSHARED, r0
168         mov.b   @(r0,r8), r5
169         extu.b  r5, r5
170         mov.l   .Lwake4, r1
171         bsrf    r1
172          nop
173 .Lwake4b:
174         bra     7b
175          mov    #0, r3
177 #ifndef __ASSUME_PRIVATE_FUTEX
178 .Lpfoff:
179         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
180 #endif
181 .Ltidoff:
182         .word   TID - TLS_PRE_TCB_SIZE
185         mov.l   @(WRITERS_QUEUED,r8), r1
186         add     #-1, r1
187         mov.l   r1, @(WRITERS_QUEUED,r8)
188         bra     9b
189          mov    #EAGAIN, r3
192         mov     r8, r4
193 #if MUTEX != 0
194         add     #MUTEX, r4
195 #endif
196         mov     #PSHARED, r0
197         mov.b   @(r0,r8), r5
198         extu.b  r5, r5
199         mov.l   .Lwake5, r1
200         bsrf    r1
201          nop
202 .Lwake5b:
203         bra     11b
204          nop
207         mov     r8, r5
208 #if MUTEX != 0
209         add     #MUTEX, r5
210 #endif
211         mov     #PSHARED, r0
212         mov.b   @(r0,r8), r6
213         extu.b  r6, r6
214         mov.l   .Lwait5, r1
215         bsrf    r1
216          mov    r2, r4
217 .Lwait5b:
218         bra     13b
219          nop
221         .align  2
222 .Lwait4:
223         .long   __lll_lock_wait-.Lwait4b
224 .Lwake4:
225         .long   __lll_unlock_wake-.Lwake4b
226 .Lwait5:
227         .long   __lll_lock_wait-.Lwait5b
228 .Lwake5:
229         .long   __lll_unlock_wake-.Lwake5b
230         .globl  pthread_rwlock_wrlock
231 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
233         .globl  __pthread_rwlock_wrlock_internal
234 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock