OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_timedwrlock.S
1 /* Copyright (C) 2003, 2007, 2008 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, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <sysdep.h>
19 #include <lowlevellock.h>
20 #include <lowlevelrwlock.h>
21 #include <pthread-errnos.h>
22 #include <tcb-offsets.h>
23 #include <bits/kernel-features.h>
24 #include "lowlevel-atomic.h"
25
26
27         .text
28
29         .globl  pthread_rwlock_timedwrlock
30         .type   pthread_rwlock_timedwrlock,@function
31         .align  5
32 pthread_rwlock_timedwrlock:
33         mov.l   r12, @-r15
34         mov.l   r10, @-r15
35         mov.l   r9, @-r15
36         mov.l   r8, @-r15
37         sts.l   pr, @-r15
38         add     #-8, r15
39         mov     r4, r8
40         mov     r5, r9
41
42         /* Get the lock.  */
43         mov     #0, r3
44         mov     #1, r4
45 #if MUTEX == 0
46         CMPXCHG (r3, @r8, r4, r2)
47 #else
48         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
49 #endif
50         bf      1f
51 2:
52         mov.l   @(WRITER,r8), r0
53         tst     r0, r0
54         bf      14f
55         mov.l   @(NR_READERS,r8), r0
56         tst     r0, r0
57         bt      5f
58 3:
59         /* Check the value of the timeout parameter.  */
60         mov.l   .L1g1, r1
61         mov.l   @(4,r9), r0
62         cmp/hs  r1, r0
63         bt      19f
64
65         mov.l   @(WRITERS_QUEUED,r8), r0
66         add     #1, r0
67         mov.l   r0, @(WRITERS_QUEUED,r8)
68         tst     r0, r0
69         bt      4f
70
71         mov.l   @(WRITERS_WAKEUP,r8), r10
72
73 #if MUTEX == 0
74         DEC (@r8, r2)
75 #else
76         DEC (@(MUTEX,r8), r2)
77 #endif
78         tst     r2, r2
79         bf      10f
80
81 11:
82         /* Get current time.  */
83         mov     r15, r4
84         mov     #0, r5
85         mov     #__NR_gettimeofday, r3
86         trapa   #0x12
87         SYSCALL_INST_PAD
88
89         mov.l   @(4,r15), r0
90         mov.w   .L1k1, r1
91         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
92         mov.l   @r9, r2
93         mov.l   @(4,r9), r3
94         mov.l   @r15, r0
95         sts     macl, r1
96         sub     r0, r2
97         clrt
98         subc    r1, r3
99         bf      15f
100         mov.l   .L1g1, r1
101         add     r1, r3
102         add     #-1, r2
103 15:
104         cmp/pz  r2
105         bf      16f             /* Time is already up.  */
106
107         /* Store relative timeout.  */
108         mov.l   r2, @r15
109         mov.l   r3, @(4,r15)
110
111         /* Futex call.  */
112         mov     r15, r7
113 #ifdef __ASSUME_PRIVATE_FUTEX
114         mov     #PSHARED, r0
115         mov.b   @(r0,r8), r5
116         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
117         xor     r0, r5
118         extu.b  r5, r5
119 #else
120         mov     #PSHARED, r0
121         mov.b   @(r0,r8), r5
122         extu.b  r5, r5
123 # if FUTEX_WAIT != 0
124         mov     #FUTEX_WAIT, r0
125         or      r0, r5
126 # endif
127         stc     gbr, r1
128         mov.w   .Lpfoff, r2
129         add     r2, r1
130         mov.l   @r1, r0
131         xor     r0, r5
132 #endif
133         mov     r10, r6
134         mov     r8, r4
135         add     #WRITERS_WAKEUP, r4
136         mov     #SYS_futex, r3
137         extu.b  r3, r3
138         trapa   #0x14
139         SYSCALL_INST_PAD
140         mov     r0, r3
141
142 17:
143         /* Reget the lock.  */
144         mov     #0, r5
145         mov     #1, r4
146 #if MUTEX == 0
147         CMPXCHG (r5, @r8, r4, r2)
148 #else
149         CMPXCHG (r5, @(MUTEX,r8), r4, r2)
150 #endif
151         bf      12f
152
153 13:
154         mov.l   @(WRITERS_QUEUED,r8), r0
155         add     #-1, r0
156         mov.l   r0, @(WRITERS_QUEUED,r8)
157         mov     #-ETIMEDOUT, r0
158         cmp/eq  r0, r3
159         bf      2b
160
161 18:
162         bra     9f
163          mov    #ETIMEDOUT, r3
164
165 19:
166         bra     9f
167          mov    #EINVAL, r3
168
169 5:
170         mov     #0, r3
171         stc     gbr, r0
172         mov.w   .Ltidoff, r1
173         mov.l   @(r0,r1), r0
174         mov.l   r0, @(WRITER,r8)
175 9:
176 #if MUTEX == 0
177         DEC (@r8, r2)
178 #else
179         DEC (@(MUTEX,r8), r2)
180 #endif
181         tst     r2, r2
182         bf      6f
183 7:
184         add     #8,r15
185         lds.l   @r15+, pr
186         mov.l   @r15+, r8
187         mov.l   @r15+, r9
188         mov.l   @r15+, r10
189         mov.l   @r15+, r12
190         rts
191          mov    r3, r0
192
193 #ifndef __ASSUME_PRIVATE_FUTEX
194 .Lpfoff:
195         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
196 #endif
197 .L1k1:
198         .word   1000
199         .align  2
200 .L1g1:
201         .long   1000000000
202
203 1:
204         mov     r8, r5
205 #if MUTEX != 0
206         add     #MUTEX, r5
207 #endif
208         mov     #PSHARED, r0
209         mov.b   @(r0,r8), r6
210         extu.b  r6, r6
211         mov.l   .Lwait6, r1
212         bsrf    r1
213          mov    r2, r4
214 .Lwait6b:
215         bra     2b
216          nop
217 14:
218         stc     gbr, r1
219         mov.w   .Ltidoff, r2
220         add     r2, r1
221         mov.l   @r1, r1
222         cmp/eq  r1, r0
223         bf      3b
224         bra     9b
225          mov    #EDEADLK, r3
226 6:
227         mov     r3, r10
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   .Lwake6, r1
236         bsrf    r1
237          nop
238 .Lwake6b:
239         bra     7b
240          mov    r10, r3
241
242 .Ltidoff:
243         .word   TID - TLS_PRE_TCB_SIZE
244
245 4:
246         /* Overflow.  */
247         mov.l   @(WRITERS_QUEUED,r8), r1
248         add     #-1, r1
249         mov.l   r1, @(WRITERS_QUEUED,r8)
250         bra     9b
251          mov    #EAGAIN, r3
252
253 10:
254         mov     r8, r4
255 #if MUTEX != 0
256         add     #MUTEX, r4
257 #endif
258         mov     #PSHARED, r0
259         mov.b   @(r0,r8), r5
260         extu.b  r5, r5
261         mov.l   .Lwake7, r1
262         bsrf    r1
263          nop
264 .Lwake7b:
265         bra     11b
266          nop
267
268 12:
269         mov     r3, r10
270         mov     r8, r5
271 #if MUTEX != 0
272         add     #MUTEX, r5
273 #endif
274         mov     #PSHARED, r0
275         mov.b   @(r0,r8), r6
276         extu.b  r6, r6
277         mov.l   .Lwait7, r1
278         bsrf    r1
279          mov    r2, r4
280 .Lwait7b:
281         bra     13b
282          mov    r10, r3
283
284 16:
285         bra     17b
286          mov    #-ETIMEDOUT, r3
287
288         .align  2
289 .Lwait6:
290         .long   __lll_lock_wait-.Lwait6b
291 .Lwake6:
292         .long   __lll_unlock_wake-.Lwake6b
293 .Lwait7:
294         .long   __lll_lock_wait-.Lwait7b
295 .Lwake7:
296         .long   __lll_unlock_wake-.Lwake7b
297         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock