2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_timedrdlock.S
blob743f283be5f6aedfe0e2adf935894d3933cab2e2
1 /* Copyright (C) 2003, 2007, 2008 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_timedrdlock
31         .type   pthread_rwlock_timedrdlock,@function
32         .align  5
33 pthread_rwlock_timedrdlock:
34         mov.l   r12, @-r15
35         mov.l   r10, @-r15
36         mov.l   r9, @-r15
37         mov.l   r8, @-r15
38         sts.l   pr, @-r15
39         add     #-8, r15
40         mov     r4, r8
41         mov     r5, r9
43         /* Get the lock.  */
44         mov     #0, r3
45         mov     #1, r4
46 #if MUTEX == 0
47         CMPXCHG (r3, @r8, r4, r2)
48 #else
49         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
50 #endif
51         bf      1f
53         mov.l   @(WRITER,r8), r0
54         tst     r0, r0
55         bf      14f
56         mov.l   @(WRITERS_QUEUED,r8), r0
57         tst     r0, r0
58         bt      5f
59         mov     #FLAGS, r0
60         mov.b   @(r0,r8), r0
61         tst     r0, r0
62         bt      5f
64         /* Check the value of the timeout parameter.  */
65         mov.l   .L1g0, r1
66         mov.l   @(4,r9), r0
67         cmp/hs  r1, r0
68         bt      19f
70         mov.l   @(READERS_QUEUED,r8), r0
71         add     #1, r0
72         mov.l   r0, @(READERS_QUEUED,r8)
73         tst     r0, r0
74         bt      4f
76         mov.l   @(READERS_WAKEUP,r8), r10
78 #if MUTEX == 0
79         DEC (@r8, r2)
80 #else
81         DEC (@(MUTEX,r8), r2)
82 #endif
83         tst     r2, r2
84         bf      10f
86 11:
87         /* Get current time.  */
88         mov     r15, r4
89         mov     #0, r5
90         mov     #__NR_gettimeofday, r3
91         trapa   #0x12
92         SYSCALL_INST_PAD
94         mov.l   @(4,r15), r0
95         mov.w   .L1k0, r1
96         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
97         mov.l   @r9, r2
98         mov.l   @(4,r9), r3
99         mov.l   @r15, r0
100         sts     macl, r1
101         sub     r0, r2
102         clrt
103         subc    r1, r3
104         bf      15f
105         mov.l   .L1g0, r1
106         add     r1, r3
107         add     #-1, r2
109         cmp/pz  r2
110         bf      16f             /* Time is already up.  */
112         /* Store relative timeout.  */
113         mov.l   r2, @r15
114         mov.l   r3, @(4,r15)
116         /* Futex call.  */
117         mov     r15, r7
118 #ifdef __ASSUME_PRIVATE_FUTEX
119         mov     #PSHARED, r0
120         mov.b   @(r0,r8), r5
121         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
122         xor     r0, r5
123         extu.b  r5, r5
124 #else
125         mov     #PSHARED, r0
126         mov.b   @(r0,r8), r5
127         extu.b  r5, r5
128 # if FUTEX_WAIT != 0
129         mov     #FUTEX_WAIT, r0
130         or      r0, r5
131 # endif
132         stc     gbr, r1
133         mov.w   .Lpfoff, r2
134         add     r2, r1
135         mov.l   @r1, r0
136         xor     r0, r5
137 #endif
138         mov     r10, r6
139         mov     r8, r4
140         add     #READERS_WAKEUP, r4
141         mov     #SYS_futex, r3
142         extu.b  r3, r3
143         trapa   #0x14
144         SYSCALL_INST_PAD
145         mov     r0, r3
148         /* Reget the lock.  */
149         mov     #0, r5
150         mov     #1, r4
151 #if MUTEX == 0
152         CMPXCHG (r5, @r8, r4, r2)
153 #else
154         CMPXCHG (r5, @(MUTEX,r8), r4, r2)
155 #endif
156         bf      12f
159         mov.l   @(READERS_QUEUED,r8), r0
160         add     #-1, r0
161         mov.l   r0, @(READERS_QUEUED,r8)
162         mov     #-ETIMEDOUT, r0
163         cmp/eq  r0, r3
164         bf      2b
167         bra     9f
168          mov    #ETIMEDOUT, r3
171         mov     #0, r3
172         mov.l   @(NR_READERS,r8), r0
173         add     #1, r0
174         mov.l   r0, @(NR_READERS,r8)
175         tst     r0, r0
176         bt      8f
179 #if MUTEX == 0
180         DEC (@r8, r2)
181 #else
182         DEC (@(MUTEX,r8), r2)
183 #endif
184         tst     r2, r2
185         bf      6f
187         add     #8,r15
188         lds.l   @r15+, pr
189         mov.l   @r15+, r8
190         mov.l   @r15+, r9
191         mov.l   @r15+, r10
192         mov.l   @r15+, r12
193         rts
194          mov    r3, r0
196 #ifndef __ASSUME_PRIVATE_FUTEX
197 .Lpfoff:
198         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
199 #endif
200         .align  2
201 .L1k0:
202         .long   1000
203 .L1g0:
204         .long   1000000000
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   .Lwait2, r1
215         bsrf    r1
216          mov    r2, r4
217 .Lwait2b:
218         bra     2b
219          nop
221         stc     gbr, r1
222         mov.w   .Ltidoff, r2
223         add     r2, r1
224         mov.l   @r1, r1
225         cmp/eq  r1, r0
226         bf      3b
227         /* Deadlock detected.  */
228         bra     9b
229          mov    #EDEADLK, r3
231 .Ltidoff:
232         .word   TID - TLS_PRE_TCB_SIZE
235         mov     r3, r10
236         mov     r8, r4
237 #if MUTEX != 0
238         add     #MUTEX, r4
239 #endif
240         mov     #PSHARED, r0
241         mov.b   @(r0,r8), r5
242         extu.b  r5, r5
243         mov.l   .Lwake2, r1
244         bsrf    r1
245          nop
246 .Lwake2b:
247         bra     7b
248          mov    r10, r3
251         /* Overflow.  */
252         mov.l   @(NR_READERS,r8), r1
253         add     #-1, r1
254         mov.l   r1, @(NR_READERS,r8)
255         bra     9b
256          mov    #EAGAIN, r3
259         /* Overflow.  */
260         mov.l   @(READERS_QUEUED,r8), r1
261         add     #-1, r1
262         mov.l   r1, @(READERS_QUEUED,r8)
263         bra     9b
264          mov    #EAGAIN, r3
267         mov     r8, r4
268 #if MUTEX != 0
269         add     #MUTEX, r4
270 #endif
271         mov     #PSHARED, r0
272         mov.b   @(r0,r8), r5
273         extu.b  r5, r5
274         mov.l   .Lwake3, r1
275         bsrf    r1
276          nop
277 .Lwake3b:
278         bra     11b
279          nop
282         mov     r3, r10
283         mov     r8, r5
284 #if MUTEX != 0
285         add     #MUTEX, r5
286 #endif
287         mov     #PSHARED, r0
288         mov.b   @(r0,r8), r6
289         extu.b  r6, r6
290         mov.l   .Lwait3, r1
291         bsrf    r1
292          mov    r2, r4
293 .Lwait3b:
294         bra     13b
295          mov    r10, r3
298         bra     17b
299          mov    #-ETIMEDOUT, r3
302         bra     9b
303          mov    #EINVAL, r3
305         .align  2
306 .Lwait2:
307         .long   __lll_lock_wait-.Lwait2b
308 .Lwake2:
309         .long   __lll_unlock_wake-.Lwake2b
310 .Lwait3:
311         .long   __lll_lock_wait-.Lwait3b
312 .Lwake3:
313         .long   __lll_unlock_wake-.Lwake3b
314         .size   pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock