* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S:
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_timedwrlock.S
blob18641fe9df294c703a16bed397413fbf5e01a1a6
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_gettimeofday        __NR_gettimeofday
27 #define SYS_futex               240
28 #define FUTEX_WAIT              0
29 #define FUTEX_WAKE              1
30 #define FUTEX_PRIVATE_FLAG    128
33         .text
35         .globl  pthread_rwlock_timedwrlock
36         .type   pthread_rwlock_timedwrlock,@function
37         .align  5
38 pthread_rwlock_timedwrlock:
39         mov.l   r12, @-r15
40         mov.l   r10, @-r15
41         mov.l   r9, @-r15
42         mov.l   r8, @-r15
43         sts.l   pr, @-r15
44         add     #-8, r15
45         mov     r4, r8
46         mov     r5, r9
48         /* Get the lock.  */
49         mov     #0, r3
50         mov     #1, r4
51 #if MUTEX == 0
52         CMPXCHG (r3, @r8, r4, r2)
53 #else
54         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
55 #endif
56         bf      1f
58         mov.l   @(WRITER,r8), r0
59         tst     r0, r0
60         bf      14f
61         mov.l   @(NR_READERS,r8), r0
62         tst     r0, r0
63         bt      5f
65         /* Check the value of the timeout parameter.  */
66         mov.l   .L1g1, r1
67         mov.l   @(4,r9), r0
68         cmp/hs  r1, r0
69         bt      19f
71         mov.l   @(WRITERS_QUEUED,r8), r0
72         add     #1, r0
73         mov.l   r0, @(WRITERS_QUEUED,r8)
74         tst     r0, r0
75         bt      4f
77         mov.l   @(WRITERS_WAKEUP,r8), r10
79 #if MUTEX == 0
80         DEC (@r8, r2)
81 #else
82         DEC (@(MUTEX,r8), r2)
83 #endif
84         tst     r2, r2
85         bf      10f
87 11:
88         /* Get current time.  */
89         mov     r15, r4
90         mov     #0, r5
91         mov     #SYS_gettimeofday, r3
92         trapa   #0x12
93         SYSCALL_INST_PAD
95         mov.l   @(4,r15), r0
96         mov.w   .L1k1, r1
97         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
98         mov.l   @r9, r2
99         mov.l   @(4,r9), r3
100         mov.l   @r15, r0
101         sts     macl, r1
102         sub     r0, r2
103         clrt
104         subc    r1, r3
105         bf      15f
106         mov.l   .L1g1, r1
107         add     r1, r3
108         add     #-1, r2
110         cmp/pz  r2
111         bf      16f             /* Time is already up.  */
113         /* Store relative timeout.  */
114         mov.l   r2, @r15
115         mov.l   r3, @(4,r15)
117         /* Futex call.  */
118         mov     r15, r7
119 #if __ASSUME_PRIVATE_FUTEX
120         mov     #PSHARED, r0
121         mov.b   @(r0,r8), r5
122         mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r0
123         xor     r0, r5
124         extu.b  r5, r5
125 #else
126         mov     #PSHARED, r0
127         mov.b   @(r0,r8), r5
128         extu.b  r5, r5
129 # if FUTEX_WAIT != 0
130         mov     #FUTEX_WAIT, r0
131         or      r0, r5
132 # endif
133         stc     gbr, r1
134         mov.w   .Lpfoff, r2
135         add     r2, r1
136         mov.l   @r1, r0
137         xor     r0, r5
138 #endif
139         mov     r10, r6
140         mov     r8, r4
141         add     #WRITERS_WAKEUP, r4
142         mov     #SYS_futex, r3
143         extu.b  r3, r3
144         trapa   #0x14
145         SYSCALL_INST_PAD
146         mov     r0, r3
149         /* Reget the lock.  */
150         mov     #0, r5
151         mov     #1, r4
152 #if MUTEX == 0
153         CMPXCHG (r5, @r8, r4, r2)
154 #else
155         CMPXCHG (r5, @(MUTEX,r8), r4, r2)
156 #endif
157         bf      12f
160         mov.l   @(WRITERS_QUEUED,r8), r0
161         add     #-1, r0
162         mov.l   r0, @(WRITERS_QUEUED,r8)
163         mov     #-ETIMEDOUT, r0
164         cmp/eq  r0, r3
165         bf      2b
168         bra     9f
169          mov    #ETIMEDOUT, r3
172         bra     9f
173          mov    #EINVAL, r3
176         mov     #0, r3
177         stc     gbr, r0
178         mov.w   .Ltidoff, r1
179         mov.l   @(r0,r1), r0
180         mov.l   r0, @(WRITER,r8)
182 #if MUTEX == 0
183         DEC (@r8, r2)
184 #else
185         DEC (@(MUTEX,r8), r2)
186 #endif
187         tst     r2, r2
188         bf      6f
190         add     #8,r15
191         lds.l   @r15+, pr
192         mov.l   @r15+, r8
193         mov.l   @r15+, r9
194         mov.l   @r15+, r10
195         mov.l   @r15+, r12
196         rts
197          mov    r3, r0
199 #if !__ASSUME_PRIVATE_FUTEX
200 .Lpfoff:
201         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
202 #endif
203 .L1k1:
204         .word   1000
205         .align  2
206 .L1g1:
207         .long   1000000000
210         mov     r8, r5
211 #if MUTEX != 0
212         add     #MUTEX, r5
213 #endif
214         mov     r2, r4
215         mov.l   .Lwait6, r1
216         bsrf    r1
217          nop
218 .Lwait6b:
219         bra     2b
220          nop
222         stc     gbr, r1
223         mov.w   .Ltidoff, r2
224         add     r2, r1
225         mov.l   @r1, r1
226         cmp/eq  r1, r0
227         bf      3b
228         bra     9b
229          mov    #EDEADLK, r3
231         mov     r8, r4
232 #if MUTEX != 0
233         add     #MUTEX, r4
234 #endif
235         mov.l   .Lwake6, r1
236         bsrf    r1
237          nop
238 .Lwake6b:
239         bra     7b
240          mov    #0, r3
242 .Ltidoff:
243         .word   TID - TLS_PRE_TCB_SIZE
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
254         mov     r8, r4
255 #if MUTEX != 0
256         add     #MUTEX, r4
257 #endif
258         mov.l   .Lwake7, r1
259         bsrf    r1
260          nop
261 .Lwake7b:
262         bra     11b
263          nop
266         mov     r8, r5
267 #if MUTEX != 0
268         add     #MUTEX, r5
269 #endif
270         mov     r2, r4
271         mov.l   .Lwait7, r1
272         bsrf    r1
273          nop
274 .Lwait7b:
275         bra     13b
276          nop
279         bra     17b
280          mov    #-ETIMEDOUT, r3
282         .align  2
283 .Lwait6:
284         .long   __lll_mutex_lock_wait-.Lwait6b
285 .Lwake6:
286         .long   __lll_mutex_unlock_wake-.Lwake6b
287 .Lwait7:
288         .long   __lll_mutex_lock_wait-.Lwait7b
289 .Lwake7:
290         .long   __lll_mutex_unlock_wake-.Lwake7b
291         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock