(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_rdlock.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_futex               240
25 #define FUTEX_WAIT              0
26 #define FUTEX_WAKE              1
27
28 #define EAGAIN          11
29 #define EDEADLK         35
30
31
32         .text
33
34         .globl  __pthread_rwlock_rdlock
35         .type   __pthread_rwlock_rdlock,@function
36         .align  5
37 __pthread_rwlock_rdlock:
38         mov.l   r12, @-r15
39         mov.l   r8, @-r15
40         sts.l   pr, @-r15
41         mov     r4, r8
42
43         /* Get the lock.  */
44         mov     #1, r3
45 #if MUTEX == 0
46         XADD    (r3, @r4, r2)
47 #else
48         XADD    (r3, @(MUTEX,r4), r2)
49 #endif
50         tst     r2, r2
51         bf      1f
52 2:
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.l   @(FLAGS,r8), r0
60         tst     r0, r0
61         bt      5f
62 3:
63         mov.l   @(READERS_QUEUED,r8), r0
64         add     #1, r0
65         mov.l   r0, @(READERS_QUEUED,r8)
66         tst     r0, r0
67         bt      4f
68
69 #if MUTEX == 0
70         DEC (@r8, r2)
71 #else
72         DEC (@(MUTEX,r8), r2)
73 #endif
74         tst     r2, r2
75         bf      10f
76 11:
77         mov     r8, r4
78         add     #READERS_WAKEUP, r4
79         mov     #FUTEX_WAIT, r5
80         mov     #0, r6
81         mov     #SYS_futex, r3
82         extu.b  r3, r3
83         trapa   #0x14
84         SYSCALL_INST_PAD
85
86         /* Reget the lock.  */
87         mov     #1, r3
88 #if MUTEX == 0
89         XADD    (r3, @r4, r2)
90 #else
91         XADD    (r3, @(MUTEX,r4), r2)
92 #endif
93         tst     r2, r2
94         bf      12f
95 13:
96         mov.l   @(READERS_QUEUED,r8), r0
97         add     #-1, r0
98         mov.l   r0, @(READERS_QUEUED,r8)
99         tst     r0, r0
100         bf      2b
101         bra     2b
102          mov.l  r0, @(READERS_WAKEUP,r8)
103
104 5:
105         mov     #0, r3
106         mov.l   @(NR_READERS,r8), r0
107         add     #1, r0
108         mov.l   r0, @(NR_READERS,r8)
109         tst     r0, r0
110         bt      8f
111
112 9:
113 #if MUTEX == 0
114         DEC (@r8, r2)
115 #else
116         DEC (@(MUTEX,r8), r2)
117 #endif
118         tst     r2, r2
119         bf      6f
120 7:
121         lds.l   @r15+, pr
122         mov.l   @r15+, r8
123         mov.l   @r15+, r12
124         rts
125          mov    r3, r0
126
127 1:
128         mov     r8, r5
129 #if MUTEX != 0
130         add     #MUTEX, r5
131 #endif
132         mov     r2, r4
133         mov.l   .Lwait0, r1
134         bsrf    r1
135          nop
136 .Lwait0b:
137         bra     2b
138          nop
139 14:
140         stc     gbr, r1
141         mov.w   .Ltcboff,r2
142         sub     r2,r1
143         mov.l   @(8,r1),r1
144         cmp/eq  r1, r0
145         bf      3b
146         /* Deadlock detected.  */
147         bra     9b
148          mov    #EDEADLK, r3
149
150 6:
151         mov     r8, r4
152 #if MUTEX != 0
153         add     #MUTEX, r4
154 #endif
155         mov.l   .Lwake0, r1
156         bsrf    r1
157          nop
158 .Lwake0b:
159         bra     7b
160          mov    #0, r3
161
162 8:
163         /* Overflow.  */
164         mov.l   @(NR_READERS,r8), r1
165         add     #-1, r1
166         mov.l   r1, @(NR_READERS,r8)
167         bra     9b
168          mov    #EAGAIN, r3
169
170 4:
171         /* Overflow.  */
172         mov.l   @(READERS_QUEUED,r8), r1
173         add     #-1, r1
174         mov.l   r1, @(READERS_QUEUED,r8)
175         bra     9b
176          mov    #EAGAIN, r3
177
178 10:
179         mov     r8, r4
180 #if MUTEX != 0
181         add     #MUTEX, r4
182 #endif
183         mov.l   .Lwake1, r1
184         bsrf    r1
185          nop
186 .Lwake1b:
187         bra     11b
188          nop
189
190 12:
191         mov     r8, r5
192 #if MUTEX != 0
193         add     #MUTEX, r5
194 #endif
195         mov     r2, r4
196         mov.l   .Lwait1, r1
197         bsrf    r1
198          nop
199 .Lwait1b:
200         bra     13b
201          nop
202
203 .Ltcboff:
204         .word   TLS_PRE_TCB_SIZE
205         .align  2
206 .Lwait0:
207         .long   __lll_mutex_lock_wait-.Lwait0b
208 .Lwake0:
209         .long   __lll_mutex_unlock_wake-.Lwake0b
210 .Lwait1:        
211         .long   __lll_mutex_lock_wait-.Lwait1b
212 .Lwake1:
213         .long   __lll_mutex_unlock_wake-.Lwake1b
214         .size   __pthread_rwlock_rdlock,.-__pthread_rwlock_rdlock
215
216         .globl  pthread_rwlock_rdlock
217 pthread_rwlock_rdlock = __pthread_rwlock_rdlock
218
219         .globl  __pthread_rwlock_rdlock_internal
220 __pthread_rwlock_rdlock_internal = __pthread_rwlock_rdlock