2.5-18.1
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_cond_broadcast.S
blob56f0aa95de4ff84987d5f024e2f302632da7fff4
1 /* Copyright (C) 2003, 2004, 2006 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 <pthread-pi-defines.h>
24 #include "lowlevel-atomic.h"
26 #define SYS_futex               240
27 #define FUTEX_WAIT              0
28 #define FUTEX_WAKE              1
29 #define FUTEX_REQUEUE           3
30 #define FUTEX_CMP_REQUEUE       4
32 #define EINVAL                  22
34         .text
36         /* int pthread_cond_broadcast (pthread_cond_t *cond) */
37         .globl  __pthread_cond_broadcast
38         .type   __pthread_cond_broadcast, @function
39         .align  5
40 __pthread_cond_broadcast:
41         mov.l   r10, @-r15
42         mov.l   r9, @-r15
43         mov.l   r8, @-r15
44         sts.l   pr, @-r15
45         mov     r4, r8
47         /* Get internal lock.  */
48         mov     #0, r3
49         mov     #1, r4
50 #if cond_lock != 0
51         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
52 #else
53         CMPXCHG (r3, @r8, r4, r2)
54 #endif
55         bf      1f
57         mov.l   @(total_seq+4,r8),r0
58         mov.l   @(total_seq,r8),r1
59         mov.l   @(wakeup_seq+4,r8), r2
60         cmp/hi  r2, r0
61         bt      3f
62         cmp/hi  r0, r2
63         bt      4f
64         mov.l   @(wakeup_seq,r8), r2
65         cmp/hi  r2, r1
66         bf      4f
69         /* Cause all currently waiting threads to recognize they are
70            woken up.  */
71         mov.l   r1, @(wakeup_seq,r8)
72         mov.l   r0, @(wakeup_seq+4,r8)
73         mov.l   r1, @(woken_seq,r8)
74         mov.l   r0, @(woken_seq+4,r8)
75         mov.l   @(broadcast_seq,r8), r2
76         add     #1, r2
77         mov.l   r2, @(broadcast_seq,r8)
78         add     r1, r1
79         mov     r1, r10
80         mov.l   r10, @(cond_futex,r8)
82         /* Get the address of the mutex used.  */
83         mov.l   @(dep_mutex,r8), r9
85         /* Unlock.  */
86 #if cond_lock != 0
87         DEC (@(cond_lock,r8), r2)
88 #else
89         DEC (@r8, r2)
90 #endif
91         tst     r2, r2
92         bf      7f
95         /* Don't use requeue for pshared condvars.  */
96         mov     #-1, r0
97         cmp/eq  r0, r9
98         mov     r8, r4
99         bt/s    9f
100          add    #cond_futex, r4
102         /* XXX: The kernel so far doesn't support requeue to PI futex.  */
103         mov.l   @(MUTEX_KIND,r9), r0
104         tst     #PI_BIT, r0
105         bf      9f
107         /* Wake up all threads.  */
108         mov     #FUTEX_CMP_REQUEUE, r5
109         mov     #1, r6
110         mov     #-1, r7
111         shlr    r7              /* r7 = 0x7fffffff */
112         mov     r9, r0
113 # if MUTEX_FUTEX != 0
114         add     #MUTEX_FUTEX, r0
115 # endif
116         mov     r10, r1
117         mov     #SYS_futex, r3
118         extu.b  r3, r3
119         trapa   #0x16
120         SYSCALL_INST_PAD
122         /* For any kind of error, which mainly is EAGAIN, we try again
123            with WAKE.  The general test also covers running on old
124            kernels.  */
125         mov     r0, r1
126         mov     #-12, r2
127         shad    r2, r1
128         not     r1, r1
129         tst     r1, r1
130         mov     r8, r4
131         bt/s    9f
132          add    #cond_futex, r4
135         mov     #0, r0
136         lds.l   @r15+, pr
137         mov.l   @r15+, r8
138         mov.l   @r15+, r9
139         rts
140          mov.l  @r15+, r10
143         /* Unlock.  */
144 #if cond_lock != 0
145         DEC (@(cond_lock,r8), r2)
146 #else
147         DEC (@r8, r2)
148 #endif
149         tst     r2, r2
150         bf      5f
152         mov     #0, r0
153         lds.l   @r15+, pr
154         mov.l   @r15+, r8
155         mov.l   @r15+, r9
156         rts
157          mov.l  @r15+, r10
160         /* Initial locking failed.  */
161         mov     r8, r5
162 #if cond_lock != 0
163         add     #cond_lock, r5
164 #endif
165         mov.l   .Lmwait5, r1
166         bsrf    r1
167          mov    r2, r4
168 .Lmwait5b:
169         bra     2b
170          nop
173         /* Unlock in loop requires wakeup.  */
174         mov     r8, r4
175 #if cond_lock != 0
176         add     #cond_lock, r4
177 #endif
178         mov.l   .Lmwake5, r1
179         bsrf    r1
180          nop
181 .Lmwake5b:
182         bra     6b
183          nop
186         /* Unlock in loop requires wakeup.  */
187         mov     r8, r4
188 #if cond_lock != 0
189         add     #cond_lock, r4
190 #endif
191         mov.l   .Lmwake6, r1
192         bsrf    r1
193          nop
194 .Lmwake6b:
195         bra     8b
196          nop
199         mov     #FUTEX_WAKE, r5
200         mov     #-1, r6
201         shlr    r6              /* r6 = 0x7fffffff */
202         mov     #0, r7
203         mov     #SYS_futex, r3
204         extu.b  r3, r3
205         trapa   #0x14
206         SYSCALL_INST_PAD
207         bra     10b
208          nop
210         .align  2
211 .Lmwait5:
212         .long   __lll_mutex_lock_wait-.Lmwait5b
213 .Lmwake5:
214         .long   __lll_mutex_unlock_wake-.Lmwake5b
215 .Lmwake6:
216         .long   __lll_mutex_unlock_wake-.Lmwake6b
217         .size   __pthread_cond_broadcast, .-__pthread_cond_broadcast
218 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
219                   GLIBC_2_3_2)