(pthread_barrier_wait): Don't save, load, and restore %esi for last thread.
[kopensolaris-gnu/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_rwlock_timedwrlock.S
1 /* Copyright (C) 2003 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 <lowlevelrwlock.h>
21 #include <tcb-offsets.h>
22 #include "lowlevel-atomic.h"
23
24 #define SYS_gettimeofday        __NR_gettimeofday
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
28
29 #define EAGAIN          11
30 #define EDEADLK         35
31 #define ETIMEDOUT       110
32
33
34         .text
35
36         .globl  pthread_rwlock_timedwrlock
37         .type   pthread_rwlock_timedwrlock,@function
38         .align  5
39 pthread_rwlock_timedwrlock:
40         mov.l   r12, @-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
47
48         /* Get the lock.  */
49         mov     #1, r3
50 #if MUTEX == 0
51         XADD    (r3, @r4, r2)
52 #else
53         XADD    (r3, @(MUTEX,r4), r2)
54 #endif
55         tst     r2, r2
56         bf      1f
57 2:
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
64 3:
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 #if MUTEX == 0
72         DEC (@r8, r2)
73 #else
74         DEC (@(MUTEX,r8), r2)
75 #endif
76         tst     r2, r2
77         bf      10f
78
79 11:
80         /* Get current time.  */
81         mov     r15, r4
82         mov     #0, r5
83         mov     #SYS_gettimeofday, r3
84         trapa   #0x12
85         SYSCALL_INST_PAD
86
87         mov.l   @(4,r15), r0
88         mov.w   .L1k1, r1
89         dmulu.l r0, r1          /* Milli seconds to nano seconds.  */
90         mov.l   @r9, r2
91         mov.l   @(4,r9), r3
92         mov.l   @r15, r0
93         sts     macl, r1
94         sub     r0, r2
95         clrt
96         subc    r1, r3
97         bf      15f
98         mov.l   .L1g1, r1
99         add     r1, r3
100         add     #-1, r2
101 15:
102         cmp/pz  r2
103         bf      16f             /* Time is already up.  */
104
105         /* Store relative timeout.  */
106         mov.l   r2, @r15
107         mov.l   r3, @(4,r15)
108
109         /* Futex call.  */
110         mov     r15, r7
111         mov     #FUTEX_WAIT, r5
112         mov     #0, r6
113         mov     r8, r4
114         add     #WRITERS_WAKEUP, r4
115         mov     #SYS_futex, r3
116         extu.b  r3, r3
117         trapa   #0x14
118         SYSCALL_INST_PAD
119         mov     r0, r3
120
121 17:
122         /* Reget the lock.  */
123         mov     r8, r4
124         mov     #1, r5
125 #if MUTEX == 0
126         XADD    (r5, @r4, r2)
127 #else
128         XADD    (r5, @(MUTEX,r4), r2)
129 #endif
130         tst     r2, r2
131         bf      12f
132
133 13:
134         mov     #-ETIMEDOUT, r0
135         cmp/eq  r0, r3
136         bt      18f
137         mov.l   @(WRITERS_QUEUED,r8), r0
138         add     #-1, r0
139         mov.l   r0, @(WRITERS_QUEUED,r8)
140         mov     #0, r0
141         bra     2b
142          mov.l  r0, @(WRITERS_WAKEUP,r8)
143
144 5:
145         mov     #0, r3
146         stc     gbr, r1
147         mov.w   .Ltcboff,r2
148         sub     r2,r1
149         mov.l   @(8,r1),r0
150         mov.l   r0, @(WRITER,r8)
151 9:
152 #if MUTEX == 0
153         DEC (@r8, r2)
154 #else
155         DEC (@(MUTEX,r8), r2)
156 #endif
157         tst     r2, r2
158         bf      6f
159 7:
160         add     #8,r15
161         lds.l   @r15+, pr
162         mov.l   @r15+, r8
163         mov.l   @r15+, r9
164         mov.l   @r15+, r12
165         rts
166          mov    r3, r0
167
168 .L1k1:
169         .word   1000
170         .align  2
171 .L1g1:
172         .long   1000000000
173
174 1:
175         mov     r8, r5
176 #if MUTEX != 0
177         add     #MUTEX, r5
178 #endif
179         mov     r2, r4
180         mov.l   .Lwait6, r1
181         bsrf    r1
182          nop
183 .Lwait6b:
184         bra     2b
185          nop
186 14:
187         stc     gbr, r1
188         mov.w   .Ltcboff,r2
189         sub     r2,r1
190         mov.l   @(8,r1),r1
191         cmp/eq  r1, r0
192         bf      3b
193         bra     9b
194          mov    #EDEADLK, r3
195 6:
196         mov     r8, r4
197 #if MUTEX != 0
198         add     #MUTEX, r4
199 #endif
200         mov.l   .Lwake6, r1
201         bsrf    r1
202          nop
203 .Lwake6b:
204         bra     7b
205          mov    #0, r3
206
207 4:
208         /* Overflow.  */
209         mov.l   @(WRITERS_QUEUED,r8), r1
210         add     #-1, r1
211         mov.l   r1, @(WRITERS_QUEUED,r8)
212         bra     9b
213          mov    #EAGAIN, r3
214
215 10:
216         mov     r8, r4
217 #if MUTEX != 0
218         add     #MUTEX, r4
219 #endif
220         mov.l   .Lwake7, r1
221         bsrf    r1
222          nop
223 .Lwake7b:
224         bra     11b
225          nop
226
227 12:
228         mov     r8, r5
229 #if MUTEX != 0
230         add     #MUTEX, r5
231 #endif
232         mov     r2, r4
233         mov.l   .Lwait7, r1
234         bsrf    r1
235          nop
236 .Lwait7b:
237         bra     13b
238          nop
239
240 16:
241         bra     17b
242          mov    #-ETIMEDOUT, r3
243
244 18:
245         bra     9b
246          mov    #ETIMEDOUT, r3
247
248 .Ltcboff:
249         .word   TLS_PRE_TCB_SIZE
250         .align  2
251 .Lwait6:        
252         .long   __lll_mutex_lock_wait-.Lwait6b
253 .Lwake6:
254         .long   __lll_mutex_unlock_wake-.Lwake6b
255 .Lwait7:        
256         .long   __lll_mutex_lock_wait-.Lwait7b
257 .Lwake7:
258         .long   __lll_mutex_unlock_wake-.Lwake7b
259         .size   pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock