Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_cond_broadcast.S
blob89b32ccf0eb7280c79d0643ed28a4de67bf5f714
1 /* Copyright (C) 2003-2014 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, see
16    <http://www.gnu.org/licenses/>.  */
18 #include <sysdep.h>
19 #include <shlib-compat.h>
20 #include <lowlevellock.h>
21 #include <lowlevelcond.h>
22 #include <kernel-features.h>
23 #include <pthread-pi-defines.h>
24 #include <pthread-errnos.h>
25 #include "lowlevel-atomic.h"
27         .text
29         /* int pthread_cond_broadcast (pthread_cond_t *cond) */
30         .globl  __pthread_cond_broadcast
31         .type   __pthread_cond_broadcast, @function
32         .align  5
33         cfi_startproc
34 __pthread_cond_broadcast:
35         mov.l   r10, @-r15
36         cfi_adjust_cfa_offset (4)
37         cfi_rel_offset (r10, 0)
38         mov.l   r9, @-r15
39         cfi_adjust_cfa_offset (4)
40         cfi_rel_offset (r9, 0)
41         mov.l   r8, @-r15
42         cfi_adjust_cfa_offset (4)
43         cfi_rel_offset (r8, 0)
44         sts.l   pr, @-r15
45         cfi_adjust_cfa_offset (4)
46         cfi_rel_offset (pr, 0)
47         mov     r4, r8
49         /* Get internal lock.  */
50         mov     #0, r3
51         mov     #1, r4
52 #if cond_lock != 0
53         CMPXCHG (r3, @(cond_lock,r8), r4, r2)
54 #else
55         CMPXCHG (r3, @r8, r4, r2)
56 #endif
57         bf      1f
59         mov.l   @(total_seq+4,r8),r0
60         mov.l   @(total_seq,r8),r1
61         mov.l   @(wakeup_seq+4,r8), r2
62         cmp/hi  r2, r0
63         bt      3f
64         cmp/hi  r0, r2
65         bt      4f
66         mov.l   @(wakeup_seq,r8), r2
67         cmp/hi  r2, r1
68         bf      4f
71         /* Cause all currently waiting threads to recognize they are
72            woken up.  */
73         mov.l   r1, @(wakeup_seq,r8)
74         mov.l   r0, @(wakeup_seq+4,r8)
75         mov.l   r1, @(woken_seq,r8)
76         mov.l   r0, @(woken_seq+4,r8)
77         mov.l   @(broadcast_seq,r8), r2
78         add     #1, r2
79         mov.l   r2, @(broadcast_seq,r8)
80         add     r1, r1
81         mov     r1, r10
82         mov.l   r10, @(cond_futex,r8)
84         /* Get the address of the mutex used.  */
85         mov.l   @(dep_mutex,r8), r9
87         /* Unlock.  */
88 #if cond_lock != 0
89         DEC (@(cond_lock,r8), r2)
90 #else
91         DEC (@r8, r2)
92 #endif
93         tst     r2, r2
94         bf      7f
97         /* Don't use requeue for pshared condvars.  */
98         mov     #-1, r0
99         cmp/eq  r0, r9
100         mov     r8, r4
101         bt/s    9f
102          add    #cond_futex, r4
104         /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
105            type of futex (private resp. shared).  */
106         mov.l   @(MUTEX_KIND,r9), r0
107         tst     #(PI_BIT|PS_BIT), r0
108         bf      9f
110         /* Wake up all threads.  */
111 #ifdef __ASSUME_PRIVATE_FUTEX
112         mov     #(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), r5
113         extu.b  r5, r5
114 #else
115         stc     gbr, r1
116         mov.w   .Lpfoff, r2
117         add     r2, r1
118         mov.l   @r1, r5
119         mov     #FUTEX_CMP_REQUEUE, r0
120         or      r0, r5
121 #endif
122         mov     #1, r6
123         mov     #-1, r7
124         shlr    r7              /* r7 = 0x7fffffff */
125         mov     r9, r0
126 # if MUTEX_FUTEX != 0
127         add     #MUTEX_FUTEX, r0
128 # endif
129         mov     r10, r1
130         mov     #SYS_futex, r3
131         extu.b  r3, r3
132         trapa   #0x16
133         SYSCALL_INST_PAD
135         /* For any kind of error, which mainly is EAGAIN, we try again
136            with WAKE.  The general test also covers running on old
137            kernels.  */
138         mov     r0, r1
139         mov     #-12, r2
140         shad    r2, r1
141         not     r1, r1
142         tst     r1, r1
143         mov     r8, r4
144         bt/s    9f
145          add    #cond_futex, r4
148         cfi_remember_state
149         lds.l   @r15+, pr
150         cfi_adjust_cfa_offset (-4)
151         cfi_restore (pr)
152         mov.l   @r15+, r8
153         cfi_adjust_cfa_offset (-4)
154         cfi_restore (r8)
155         mov.l   @r15+, r9
156         cfi_adjust_cfa_offset (-4)
157         cfi_restore (r9)
158         mov.l   @r15+, r10
159         cfi_adjust_cfa_offset (-4)
160         cfi_restore (r10)
161         rts
162          mov    #0, r0
163         cfi_restore_state
166         /* Unlock.  */
167 #if cond_lock != 0
168         DEC (@(cond_lock,r8), r2)
169 #else
170         DEC (@r8, r2)
171 #endif
172         tst     r2, r2
173         bf      5f
175         cfi_remember_state
176         lds.l   @r15+, pr
177         cfi_adjust_cfa_offset (-4)
178         cfi_restore (pr)
179         mov.l   @r15+, r8
180         cfi_adjust_cfa_offset (-4)
181         cfi_restore (r8)
182         mov.l   @r15+, r9
183         cfi_adjust_cfa_offset (-4)
184         cfi_restore (r9)
185         mov.l   @r15+, r10
186         cfi_adjust_cfa_offset (-4)
187         cfi_restore (r10)
188         rts
189          mov    #0, r0
190         cfi_restore_state
193         /* Initial locking failed.  */
194         mov     r8, r5
195 #if cond_lock != 0
196         add     #cond_lock, r5
197 #endif
198         mov.l   @(dep_mutex,r8), r0
199         cmp/eq  #-1, r0
200         bf/s    99f
201          mov    #LLL_PRIVATE, r6
202         mov     #LLL_SHARED, r6
204         extu.b  r6, r6
205         mov.l   .Lwait5, r1
206         bsrf    r1
207          mov    r2, r4
208 .Lwait5b:
209         bra     2b
210          nop
213         /* Unlock in loop requires wakeup.  */
214         mov     r8, r4
215 #if cond_lock != 0
216         add     #cond_lock, r4
217 #endif
218         mov.l   @(dep_mutex,r8), r0
219         cmp/eq  #-1, r0
220         bf/s    99f
221          mov    #LLL_PRIVATE, r5
222         mov     #LLL_SHARED, r5
224         mov.l   .Lwake5, r1
225         bsrf    r1
226          extu.b r5, r5
227 .Lwake5b:
228         bra     6b
229          nop
232         /* Unlock in loop requires wakeup.  */
233         mov     r8, r4
234 #if cond_lock != 0
235         add     #cond_lock, r4
236 #endif
237         mov     #-1, r0
238         cmp/eq  r0, r9
239         bf/s    99f
240          mov    #LLL_PRIVATE, r5
241         mov     #LLL_SHARED, r5
243         mov.l   .Lwake6, r1
244         bsrf    r1
245          extu.b r5, r5
246 .Lwake6b:
247         bra     8b
248          nop
251         mov     #-1, r0
252         cmp/eq  r0, r9
253         bt/s    99f
254          mov    #FUTEX_WAKE, r5
255 #ifdef __ASSUME_PRIVATE_FUTEX
256         mov     #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
257         extu.b  r5, r5
258 #else
259         stc     gbr, r1
260         mov.w   .Lpfoff, r2
261         add     r2, r1
262         mov.l   @r1, r5
263         mov     #FUTEX_WAKE, r0
264         or      r0, r5
265 #endif
267         mov     #-1, r6
268         shlr    r6              /* r6 = 0x7fffffff */
269         mov     #0, r7
270         mov     #SYS_futex, r3
271         extu.b  r3, r3
272         trapa   #0x14
273         SYSCALL_INST_PAD
274         bra     10b
275          nop
276         cfi_endproc
278 #ifndef __ASSUME_PRIVATE_FUTEX
279 .Lpfoff:
280         .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
281 #endif
283         .align  2
284 .Lwait5:
285         .long   __lll_lock_wait-.Lwait5b
286 .Lwake5:
287         .long   __lll_unlock_wake-.Lwake5b
288 .Lwake6:
289         .long   __lll_unlock_wake-.Lwake6b
290         .size   __pthread_cond_broadcast, .-__pthread_cond_broadcast
291 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
292                   GLIBC_2_3_2)