(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_cond_broadcast.S
blob6bd6e60ec17c5e63469b8349995b1362a33721d1
1 /* Copyright (C) 2003, 2004 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 <shlib-compat.h>
21 #include <lowlevelcond.h>
22 #include <kernel-features.h>
23 #include "lowlevel-atomic.h"
25 #define SYS_futex               240
26 #define FUTEX_WAIT              0
27 #define FUTEX_WAKE              1
28 #define FUTEX_REQUEUE           3
29 #define FUTEX_CMP_REQUEUE       4
31 #define EINVAL                  22
33         .text
35         /* int pthread_cond_broadcast (pthread_cond_t *cond) */
36         .globl  __pthread_cond_broadcast
37         .type   __pthread_cond_broadcast, @function
38         .align  5
39 __pthread_cond_broadcast:
40         mov.l   r10, @-r15
41         mov.l   r9, @-r15
42         mov.l   r8, @-r15
43         sts.l   pr, @-r15
44         mov     r4, r8
46         /* Get internal lock.  */
47         mov     #0, r3
48         mov     #1, r4
49 #if cond_lock != 0
50         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
51 #else
52         CMPXCHG (r3, @r8, r4, r2)
53 #endif
54         bf      1f
56         mov.l   @(total_seq+4,r8),r0
57         mov.l   @(total_seq,r8),r1
58         mov.l   @(wakeup_seq+4,r8), r2
59         cmp/hi  r2, r0
60         bt      3f
61         cmp/hi  r0, r2
62         bt      4f
63         mov.l   @(wakeup_seq,r8), r2
64         cmp/hi  r2, r1
65         bf      4f
68         /* Cause all currently waiting threads to recognize they are
69            woken up.  */
70         mov.l   r1, @(wakeup_seq,r8)
71         mov.l   r0, @(wakeup_seq+4,r8)
72         mov.l   r1, @(woken_seq,r8)
73         mov.l   r0, @(woken_seq+4,r8)
74         mov.l   @(broadcast_seq,r8), r2
75         add     #1, r2
76         mov.l   r2, @(broadcast_seq,r8)
77         add     r1, r1
78         mov     r1, r10
79         mov.l   r10, @(cond_futex,r8)
81         /* Get the address of the mutex used.  */
82         mov.l   @(dep_mutex,r8), r9
84         /* Unlock.  */
85 #if cond_lock != 0
86         DEC (@(cond_lock,r8), r2)
87 #else
88         DEC (@r8, r2)
89 #endif
90         tst     r2, r2
91         bf      7f
94         /* Don't use requeue for pshared condvars.  */
95         mov     #-1, r0
96         cmp/eq  r0, r9
97         mov     r8, r4
98         bt/s    9f
99          add    #cond_futex, r4
101         /* Wake up all threads.  */
102         mov     #FUTEX_CMP_REQUEUE, r5
103         mov     #1, r6
104         mov     #-1, r7
105         shlr    r7              /* r7 = 0x7fffffff */
106         mov     r9, r0
107 # if MUTEX_FUTEX != 0
108         add     #MUTEX_FUTEX, r0
109 # endif
110         mov     r10, r1
111         mov     #SYS_futex, r3
112         extu.b  r3, r3
113         trapa   #0x16
114         SYSCALL_INST_PAD
116         /* For any kind of error, which mainly is EAGAIN, we try again
117            with WAKE.  The general test also covers running on old
118            kernels.  */
119         mov     r0, r1
120         mov     #-12, r2
121         shad    r2, r1
122         not     r1, r1
123         tst     r1, r1
124         mov     r8, r4
125         bt/s    9f
126          add    #cond_futex, r4
129         mov     #0, r0
130         lds.l   @r15+, pr
131         mov.l   @r15+, r8
132         mov.l   @r15+, r9
133         rts
134          mov.l  @r15+, r10
137         /* Unlock.  */
138 #if cond_lock != 0
139         DEC (@(cond_lock,r8), r2)
140 #else
141         DEC (@r8, r2)
142 #endif
143         tst     r2, r2
144         bf      5f
146         mov     #0, r0
147         lds.l   @r15+, pr
148         mov.l   @r15+, r8
149         mov.l   @r15+, r9
150         rts
151          mov.l  @r15+, r10
154         /* Initial locking failed.  */
155         mov     r8, r5
156 #if cond_lock != 0
157         add     #cond_lock, r5
158 #endif
159         mov.l   .Lmwait5, r1
160         bsrf    r1
161          mov    r2, r4
162 .Lmwait5b:
163         bra     2b
164          nop
167         /* Unlock in loop requires wakeup.  */
168         mov     r8, r4
169 #if cond_lock != 0
170         add     #cond_lock, r4
171 #endif
172         mov.l   .Lmwake5, r1
173         bsrf    r1
174          nop
175 .Lmwake5b:
176         bra     6b
177          nop
180         /* Unlock in loop requires wakeup.  */
181         mov     r8, r4
182 #if cond_lock != 0
183         add     #cond_lock, r4
184 #endif
185         mov.l   .Lmwake6, r1
186         bsrf    r1
187          nop
188 .Lmwake6b:
189         bra     8b
190          nop
193         mov     #FUTEX_WAKE, r5
194         mov     #-1, r6
195         shlr    r6              /* r6 = 0x7fffffff */
196         mov     #0, r7
197         mov     #SYS_futex, r3
198         extu.b  r3, r3
199         trapa   #0x14
200         SYSCALL_INST_PAD
201         bra     10b
202          nop
204         .align  2
205 .Lmwait5:
206         .long   __lll_mutex_lock_wait-.Lmwait5b
207 .Lmwake5:
208         .long   __lll_mutex_unlock_wake-.Lmwake5b
209 .Lmwake6:
210         .long   __lll_mutex_unlock_wake-.Lmwake6b
211         .size   __pthread_cond_broadcast, .-__pthread_cond_broadcast
212 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
213                   GLIBC_2_3_2)