OSDN Git Service

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