2.9
[glibc/nacl-glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_timedwrlock.S
blob307494c8c28b1f846474e8a4a68ea3f1d3e3a506
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_timedwrlock
31         .type   pthread_rwlock_timedwrlock,@function
32         .align  5
33 pthread_rwlock_timedwrlock:
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   @(NR_READERS,r8), r0
57         tst     r0, r0
58         bt      5f
60         /* Check the value of the timeout parameter.  */
61         mov.l   .L1g1, r1
62         mov.l   @(4,r9), r0
63         cmp/hs  r1, r0
64         bt      19f
66         mov.l   @(WRITERS_QUEUED,r8), r0
67         add     #1, r0
68         mov.l   r0, @(WRITERS_QUEUED,r8)
69         tst     r0, r0
70         bt      4f
72         mov.l   @(WRITERS_WAKEUP,r8), r10
74 #if MUTEX == 0
75         DEC (@r8, r2)
76 #else
77         DEC (@(MUTEX,r8), r2)
78 #endif
79         tst     r2, r2
80         bf      10f
82 11:
83         /* Get current time.  */
84         mov     r15, r4
85         mov     #0, r5
86         mov     #__NR_gettimeofday, r3
87         trapa   #0x12
88         SYSCALL_INST_PAD
90         mov.l   @(4,r15), r0
91         mov.w   .L1k1, r1
92         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
93         mov.l   @r9, r2
94         mov.l   @(4,r9), r3
95         mov.l   @r15, r0
96         sts     macl, r1
97         sub     r0, r2
98         clrt
99         subc    r1, r3
100         bf      15f
101         mov.l   .L1g1, r1
102         add     r1, r3
103         add     #-1, r2
105         cmp/pz  r2
106         bf      16f             /* Time is already up.  */
108         /* Store relative timeout.  */
109         mov.l   r2, @r15
110         mov.l   r3, @(4,r15)
112         /* Futex call.  */
113         mov     r15, r7
114 #ifdef __ASSUME_PRIVATE_FUTEX
115         mov     #PSHARED, r0
116         mov.b   @(r0,r8), r5
117         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
118         xor     r0, r5
119         extu.b  r5, r5
120 #else
121         mov     #PSHARED, r0
122         mov.b   @(r0,r8), r5
123         extu.b  r5, r5
124 # if FUTEX_WAIT != 0
125         mov     #FUTEX_WAIT, r0
126         or      r0, r5
127 # endif
128         stc     gbr, r1
129         mov.w   .Lpfoff, r2
130         add     r2, r1
131         mov.l   @r1, r0
132         xor     r0, r5
133 #endif
134         mov     r10, r6
135         mov     r8, r4
136         add     #WRITERS_WAKEUP, r4
137         mov     #SYS_futex, r3
138         extu.b  r3, r3
139         trapa   #0x14
140         SYSCALL_INST_PAD
141         mov     r0, r3
144         /* Reget the lock.  */
145         mov     #0, r5
146         mov     #1, r4
147 #if MUTEX == 0
148         CMPXCHG (r5, @r8, r4, r2)
149 #else
150         CMPXCHG (r5, @(MUTEX,r8), r4, r2)
151 #endif
152         bf      12f
155         mov.l   @(WRITERS_QUEUED,r8), r0
156         add     #-1, r0
157         mov.l   r0, @(WRITERS_QUEUED,r8)
158         mov     #-ETIMEDOUT, r0
159         cmp/eq  r0, r3
160         bf      2b
163         bra     9f
164          mov    #ETIMEDOUT, r3
167         bra     9f
168          mov    #EINVAL, r3
171         mov     #0, r3
172         stc     gbr, r0
173         mov.w   .Ltidoff, r1
174         mov.l   @(r0,r1), r0
175         mov.l   r0, @(WRITER,r8)
177 #if MUTEX == 0
178         DEC (@r8, r2)
179 #else
180         DEC (@(MUTEX,r8), r2)
181 #endif
182         tst     r2, r2
183         bf      6f
185         add     #8,r15
186         lds.l   @r15+, pr
187         mov.l   @r15+, r8
188         mov.l   @r15+, r9
189         mov.l   @r15+, r10
190         mov.l   @r15+, r12
191         rts
192          mov    r3, r0
194 #ifndef __ASSUME_PRIVATE_FUTEX
195 .Lpfoff:
196         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
197 #endif
198 .L1k1:
199         .word   1000
200         .align  2
201 .L1g1:
202         .long   1000000000
205         mov     r8, r5
206 #if MUTEX != 0
207         add     #MUTEX, r5
208 #endif
209         mov     #PSHARED, r0
210         mov.b   @(r0,r8), r6
211         extu.b  r6, r6
212         mov.l   .Lwait6, r1
213         bsrf    r1
214          mov    r2, r4
215 .Lwait6b:
216         bra     2b
217          nop
219         stc     gbr, r1
220         mov.w   .Ltidoff, r2
221         add     r2, r1
222         mov.l   @r1, r1
223         cmp/eq  r1, r0
224         bf      3b
225         bra     9b
226          mov    #EDEADLK, r3
228         mov     r3, r10
229         mov     r8, r4
230 #if MUTEX != 0
231         add     #MUTEX, r4
232 #endif
233         mov     #PSHARED, r0
234         mov.b   @(r0,r8), r5
235         extu.b  r5, r5
236         mov.l   .Lwake6, r1
237         bsrf    r1
238          nop
239 .Lwake6b:
240         bra     7b
241          mov    r10, r3
243 .Ltidoff:
244         .word   TID - TLS_PRE_TCB_SIZE
247         /* Overflow.  */
248         mov.l   @(WRITERS_QUEUED,r8), r1
249         add     #-1, r1
250         mov.l   r1, @(WRITERS_QUEUED,r8)
251         bra     9b
252          mov    #EAGAIN, r3
255         mov     r8, r4
256 #if MUTEX != 0
257         add     #MUTEX, r4
258 #endif
259         mov     #PSHARED, r0
260         mov.b   @(r0,r8), r5
261         extu.b  r5, r5
262         mov.l   .Lwake7, r1
263         bsrf    r1
264          nop
265 .Lwake7b:
266         bra     11b
267          nop
270         mov     r3, r10
271         mov     r8, r5
272 #if MUTEX != 0
273         add     #MUTEX, r5
274 #endif
275         mov     #PSHARED, r0
276         mov.b   @(r0,r8), r6
277         extu.b  r6, r6
278         mov.l   .Lwait7, r1
279         bsrf    r1
280          mov    r2, r4
281 .Lwait7b:
282         bra     13b
283          mov    r10, r3
286         bra     17b
287          mov    #-ETIMEDOUT, r3
289         .align  2
290 .Lwait6:
291         .long   __lll_lock_wait-.Lwait6b
292 .Lwake6:
293         .long   __lll_unlock_wake-.Lwake6b
294 .Lwait7:
295         .long   __lll_lock_wait-.Lwait7b
296 .Lwake7:
297         .long   __lll_unlock_wake-.Lwake7b
298         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock