(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_wrlock.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_wrlock
35         .type   __pthread_rwlock_wrlock,@function
36         .align  5
37 __pthread_rwlock_wrlock:
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   @(NR_READERS,r8), r0
57         tst     r0, r0
58         bt      5f
59 3:
60         mov.l   @(WRITERS_QUEUED,r8), r0
61         add     #1, r0
62         mov.l   r0, @(WRITERS_QUEUED,r8)
63         tst     r0, r0
64         bt      4f
65
66 #if MUTEX == 0
67         DEC (@r8, r2)
68 #else
69         DEC (@(MUTEX,r8), r2)
70 #endif
71         tst     r2, r2
72         bf      10f
73 11:
74         mov     r8, r4
75         add     #WRITERS_WAKEUP, r4
76         mov     #FUTEX_WAIT, r5
77         mov     #0, r6
78         mov     #SYS_futex, r3
79         extu.b  r3, r3
80         trapa   #0x14
81         SYSCALL_INST_PAD
82
83         /* Reget the lock.  */
84         mov     #1, r3
85 #if MUTEX == 0
86         XADD    (r3, @r4, r2)
87 #else
88         XADD    (r3, @(MUTEX,r4), r2)
89 #endif
90         tst     r2, r2
91         bf      12f
92 13:
93         mov.l   @(READERS_QUEUED,r8), r0
94         add     #-1, r0
95         mov.l   r0, @(READERS_QUEUED,r8)
96         mov     #0, r0
97         bra     2b
98          mov.l  r0, @(WRITERS_WAKEUP,r8)
99
100 5:
101         mov     #0, r3
102         stc     gbr, r1
103         mov.w   .Ltcboff,r2
104         sub     r2,r1
105         mov.l   @(8,r1),r0
106         mov.l   r0, @(WRITER,r8)
107 9:
108 #if MUTEX == 0
109         DEC (@r8, r2)
110 #else
111         DEC (@(MUTEX,r8), r2)
112 #endif
113         tst     r2, r2
114         bf      6f
115 7:
116         lds.l   @r15+, pr
117         mov.l   @r15+, r8
118         mov.l   @r15+, r12
119         rts
120          mov    r3, r0
121
122 1:
123         mov     r8, r5
124 #if MUTEX != 0
125         add     #MUTEX, r5
126 #endif
127         mov     r2, r4
128         mov.l   .Lwait4, r1
129         bsrf    r1
130          nop
131 .Lwait4b:
132         bra     2b
133          nop
134 14:
135         stc     gbr, r1
136         mov.w   .Ltcboff,r2
137         sub     r2,r1
138         mov.l   @(8,r1),r1
139         cmp/eq  r1, r0
140         bf      3b
141         bra     9b
142          mov    #EDEADLK, r3
143 6:
144         mov     r8, r4
145 #if MUTEX != 0
146         add     #MUTEX, r4
147 #endif
148         mov.l   .Lwake4, r1
149         bsrf    r1
150          nop
151 .Lwake4b:
152         bra     7b
153          mov    #0, r3
154
155 4:
156         mov.l   @(WRITERS_QUEUED,r8), r1
157         add     #-1, r1
158         mov.l   r1, @(WRITERS_QUEUED,r8)
159         bra     9b
160          mov    #EAGAIN, r3
161
162 10:
163         mov     r8, r4
164 #if MUTEX != 0
165         add     #MUTEX, r4
166 #endif
167         mov.l   .Lwake5, r1
168         bsrf    r1
169          nop
170 .Lwake5b:
171         bra     11b
172          nop
173
174 12:
175         mov     r8, r5
176 #if MUTEX != 0
177         add     #MUTEX, r5
178 #endif
179         mov     r2, r4
180         mov.l   .Lwait5, r1
181         bsrf    r1
182          nop
183 .Lwait5b:
184         bra     13b
185          nop
186
187 .Ltcboff:
188         .word   TLS_PRE_TCB_SIZE
189         .align  2
190 .Lwait4:        
191         .long   __lll_mutex_lock_wait-.Lwait4b
192 .Lwake4:
193         .long   __lll_mutex_unlock_wake-.Lwake4b
194 .Lwait5:        
195         .long   __lll_mutex_lock_wait-.Lwait5b
196 .Lwake5:
197         .long   __lll_mutex_unlock_wake-.Lwake5b
198         .globl  pthread_rwlock_wrlock
199 pthread_rwlock_wrlock = __pthread_rwlock_wrlock
200
201         .globl  __pthread_rwlock_wrlock_internal
202 __pthread_rwlock_wrlock_internal = __pthread_rwlock_wrlock