* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_wrlock.S
blob13a2fda9fd18def239663e18425a778aa0beb275
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 <lowlevelrwlock.h>
21 #include <pthread-errnos.h>
22 #include <tcb-offsets.h>
23 #include <kernel-features.h>
24 #include "lowlevel-atomic.h"
26 #define SYS_futex               240
27 #define FUTEX_WAIT              0
28 #define FUTEX_WAKE              1
29 #define FUTEX_PRIVATE_FLAG      128
32         .text
34         .globl  __pthread_rwlock_wrlock
35         .type   __pthread_rwlock_wrlock,@function
36         .align  5
37 __pthread_rwlock_wrlock:
38         mov.l   r12, @-r15
39         mov.l   r9, @-r15
40         mov.l   r8, @-r15
41         sts.l   pr, @-r15
42         mov     r4, r8
44         /* Get the lock.  */
45         mov     #0, r3
46         mov     #1, r4
47 #if MUTEX == 0
48         CMPXCHG (r3, @r8, r4, r2)
49 #else
50         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
51 #endif
52         bf      1f
54         mov.l   @(WRITER,r8), r0
55         tst     r0, r0
56         bf      14f
57         mov.l   @(NR_READERS,r8), r0
58         tst     r0, r0
59         bt      5f
61         mov.l   @(WRITERS_QUEUED,r8), r0
62         add     #1, r0
63         mov.l   r0, @(WRITERS_QUEUED,r8)
64         tst     r0, r0
65         bt      4f
67         mov.l   @(WRITERS_WAKEUP,r8), r9
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         mov     r8, r4
78         add     #WRITERS_WAKEUP, r4
79 #if __ASSUME_PRIVATE_FUTEX
80         mov     #PSHARED, r0
81         mov.b   @(r0,r8), r5
82         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
83         xor     r0, r5
84         extu.b  r5, r5
85 #else
86         mov     #PSHARED, r0
87         mov.b   @(r0,r8), r5
88         extu.b  r5, r5
89 # if FUTEX_WAIT != 0
90         mov     #FUTEX_WAIT, r0
91         or      r0, r5
92 # endif
93         stc     gbr, r1
94         mov.w   .Lpfoff, r2
95         add     r2, r1
96         mov.l   @r1, r0
97         xor     r0, r5
98 #endif
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
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
116         mov.l   @(WRITERS_QUEUED,r8), r0
117         add     #-1, r0
118         bra     2b
119          mov.l  r0, @(WRITERS_QUEUED,r8)
122         mov     #0, r3
123         stc     gbr, r0
124         mov.w   .Ltidoff, r1
125         mov.l   @(r0,r1), r0
126         mov.l   r0, @(WRITER,r8)
128 #if MUTEX == 0
129         DEC (@r8, r2)
130 #else
131         DEC (@(MUTEX,r8), r2)
132 #endif
133         tst     r2, r2
134         bf      6f
136         lds.l   @r15+, pr
137         mov.l   @r15+, r8
138         mov.l   @r15+, r9
139         mov.l   @r15+, r12
140         rts
141          mov    r3, r0
144         mov     r8, r5
145 #if MUTEX != 0
146         add     #MUTEX, r5
147 #endif
148         mov     r2, r4
149         mov.l   .Lwait4, r1
150         bsrf    r1
151          nop
152 .Lwait4b:
153         bra     2b
154          nop
156         stc     gbr, r1
157         mov.w   .Ltidoff, r2
158         add     r2, r1
159         mov.l   @r1, r1
160         cmp/eq  r1, r0
161         bf      3b
162         bra     9b
163          mov    #EDEADLK, r3
165         mov     r8, r4
166 #if MUTEX != 0
167         add     #MUTEX, r4
168 #endif
169         mov.l   .Lwake4, r1
170         bsrf    r1
171          nop
172 .Lwake4b:
173         bra     7b
174          mov    #0, r3
176 #if !__ASSUME_PRIVATE_FUTEX
177 .Lpfoff:
178         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
179 #endif
180 .Ltidoff:
181         .word   TID - TLS_PRE_TCB_SIZE
184         mov.l   @(WRITERS_QUEUED,r8), r1
185         add     #-1, r1
186         mov.l   r1, @(WRITERS_QUEUED,r8)
187         bra     9b
188          mov    #EAGAIN, r3
191         mov     r8, r4
192 #if MUTEX != 0
193         add     #MUTEX, r4
194 #endif
195         mov.l   .Lwake5, r1
196         bsrf    r1
197          nop
198 .Lwake5b:
199         bra     11b
200          nop
203         mov     r8, r5
204 #if MUTEX != 0
205         add     #MUTEX, r5
206 #endif
207         mov     r2, r4
208         mov.l   .Lwait5, r1
209         bsrf    r1
210          nop
211 .Lwait5b:
212         bra     13b
213          nop
215         .align  2
216 .Lwait4:
217         .long   __lll_mutex_lock_wait-.Lwait4b
218 .Lwake4:
219         .long   __lll_mutex_unlock_wake-.Lwake4b
220 .Lwait5:
221         .long   __lll_mutex_lock_wait-.Lwait5b
222 .Lwake5:
223         .long   __lll_mutex_unlock_wake-.Lwake5b
224         .globl  pthread_rwlock_wrlock
225 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
227         .globl  __pthread_rwlock_wrlock_internal
228 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock