Update copyright notices with scripts/update-copyrights
[glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_barrier_wait.S
blob946b1d746f05c7eb23c79c4737ec89eb2fb6be00
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 <lowlevellock.h>
20 #include <lowlevelbarrier.h>
21 #include "lowlevel-atomic.h"
23         .text
25         .globl  pthread_barrier_wait
26         .type   pthread_barrier_wait,@function
27         .align  5
28         cfi_startproc
29 pthread_barrier_wait:
30         mov.l   r9, @-r15
31         cfi_adjust_cfa_offset (4)
32         cfi_rel_offset (r9, 0)
33         mov.l   r8, @-r15
34         cfi_adjust_cfa_offset (4)
35         cfi_rel_offset (r8, 0)
36         sts.l   pr, @-r15
37         cfi_adjust_cfa_offset (4)
38         cfi_rel_offset (pr, 0)
39         mov     r4, r8
41         /* Get the mutex.  */
42         mov     #0, r3
43         mov     #1, r4
44         CMPXCHG (r3, @(MUTEX,r8), r4, r2)
45         bf      1f
47         /* One less waiter.  If this was the last one needed wake
48            everybody.  */
50         mov.l   @(LEFT,r8), r0
51         add     #-1, r0
52         mov.l   r0, @(LEFT,r8)
53         tst     r0, r0
54         bt      3f
56         /* There are more threads to come.  */
57         mov.l   @(CURR_EVENT,r8), r6
59         /* Release the mutex.  */
60         DEC (@(MUTEX,r8), r2)
61         tst     r2, r2
62         bf      6f
64         /* Wait for the remaining threads.  The call will return immediately
65            if the CURR_EVENT memory has meanwhile been changed.  */
66         mov     r8, r4
67 #if CURR_EVENT != 0
68         add     #CURR_EVENT, r4
69 #endif
70 #if FUTEX_WAIT == 0
71         mov.l   @(PRIVATE,r8), r5
72 #else
73         mov     #FUTEX_WAIT, r5
74         mov.l   @(PRIVATE,r8), r0
75         or      r0, r5
76 #endif
77         mov     #0, r7
79         mov     #SYS_futex, r3
80         extu.b  r3, r3
81         trapa   #0x14
82         SYSCALL_INST_PAD
84         /* Don't return on spurious wakeups.  The syscall does not change
85            any register except r0 so there is no need to reload any of
86            them.  */
87         mov.l   @(CURR_EVENT,r8), r0
88         cmp/eq  r0, r6
89         bt      8b
91         /* Increment LEFT.  If this brings the count back to the
92            initial count unlock the object.  */
93         mov     #1, r3
94         mov.l   @(INIT_COUNT,r8), r4
95         XADD    (r3, @(LEFT,r8), r2, r5)
96         add     #-1, r4
97         cmp/eq  r2, r4
98         bf      10f
100         /* Release the mutex.  We cannot release the lock before
101            waking the waiting threads since otherwise a new thread might
102            arrive and gets waken up, too.  */
103         DEC (@(MUTEX,r8), r2)
104         tst     r2, r2
105         bf      9f
108         cfi_remember_state
109         lds.l   @r15+, pr
110         cfi_adjust_cfa_offset (-4)
111         cfi_restore (pr)
112         mov.l   @r15+, r8
113         cfi_adjust_cfa_offset (-4)
114         cfi_restore (r8)
115         mov.l   @r15+, r9
116         cfi_adjust_cfa_offset (-4)
117         cfi_restore (r9)
118         rts
119          mov    #0, r0          /* != PTHREAD_BARRIER_SERIAL_THREAD */
120         cfi_restore_state
123         /* The necessary number of threads arrived.  */
124         mov.l   @(CURR_EVENT,r8), r1
125         add     #1, r1
126         mov.l   r1, @(CURR_EVENT,r8)
128         /* Wake up all waiters.  The count is a signed number in the kernel
129            so 0x7fffffff is the highest value.  */
130         mov.l   .Lall, r6
131         mov     r8, r4
132 #if CURR_EVENT != 0
133         add     #CURR_EVENT, r4
134 #endif
135         mov     #0, r7
136         mov     #FUTEX_WAKE, r5
137         mov.l   @(PRIVATE,r8), r0
138         or      r0, r5
139         mov     #SYS_futex, r3
140         extu.b  r3, r3
141         trapa   #0x14
142         SYSCALL_INST_PAD
144         /* Increment LEFT.  If this brings the count back to the
145            initial count unlock the object.  */
146         mov     #1, r3
147         mov.l   @(INIT_COUNT,r8), r4
148         XADD    (r3, @(LEFT,r8), r2, r5)
149         add     #-1, r4
150         cmp/eq  r2, r4
151         bf      5f
153         /* Release the mutex.  */
154         DEC (@(MUTEX,r8), r2)
155         tst     r2, r2
156         bf      4f
158         cfi_remember_state
159         lds.l   @r15+, pr
160         cfi_adjust_cfa_offset (-4)
161         cfi_restore (pr)
162         mov.l   @r15+, r8
163         cfi_adjust_cfa_offset (-4)
164         cfi_restore (r8)
165         mov.l   @r15+, r9
166         cfi_adjust_cfa_offset (-4)
167         cfi_restore (r9)
168         rts
169          mov    #-1, r0         /* == PTHREAD_BARRIER_SERIAL_THREAD */
170         cfi_restore_state
173         mov.l   @(PRIVATE,r8), r6
174         mov     #LLL_SHARED, r0
175         extu.b  r0, r0
176         xor     r0, r6
177         mov     r2, r4
178         mov     r8, r5
179         mov.l   .Lwait0, r1
180         bsrf    r1
181          add    #MUTEX, r5
182 .Lwait0b:
183         bra     2b
184          nop
187         mov.l   @(PRIVATE,r8), r5
188         mov     #LLL_SHARED, r0
189         extu.b  r0, r0
190         xor     r0, r5
191         mov     r8, r4
192         mov.l   .Lwake0, r1
193         bsrf    r1
194          add    #MUTEX, r4
195 .Lwake0b:
196         bra     5b
197          nop
200         mov     r6, r9
201         mov.l   @(PRIVATE,r8), r5
202         mov     #LLL_SHARED, r0
203         extu.b  r0, r0
204         xor     r0, r5
205         mov     r8, r4
206         mov.l   .Lwake1, r1
207         bsrf    r1
208          add    #MUTEX, r4
209 .Lwake1b:
210         bra     7b
211          mov    r9, r6
214         mov     r6, r9
215         mov.l   @(PRIVATE,r8), r5
216         mov     #LLL_SHARED, r0
217         extu.b  r0, r0
218         xor     r0, r5
219         mov     r8, r4
220         mov.l   .Lwake2, r1
221         bsrf    r1
222          add    #MUTEX, r4
223 .Lwake2b:
224         bra     10b
225          mov    r9, r6
226         cfi_endproc
228         .align  2
229 .Lall:
230         .long   0x7fffffff
231 .Lwait0:
232         .long   __lll_lock_wait-.Lwait0b
233 .Lwake0:
234         .long   __lll_unlock_wake-.Lwake0b
235 .Lwake1:
236         .long   __lll_unlock_wake-.Lwake1b
237 .Lwake2:
238         .long   __lll_unlock_wake-.Lwake2b
239         .size   pthread_barrier_wait,.-pthread_barrier_wait