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/>. */
19 #include <lowlevellock.h>
20 #include <lowlevelbarrier.h>
21 #include "lowlevel-atomic.h"
25 .globl pthread_barrier_wait
26 .type pthread_barrier_wait,@function
31 cfi_adjust_cfa_offset (4)
32 cfi_rel_offset (r9, 0)
34 cfi_adjust_cfa_offset (4)
35 cfi_rel_offset (r8, 0)
37 cfi_adjust_cfa_offset (4)
38 cfi_rel_offset (pr, 0)
44 CMPXCHG (r3, @(MUTEX,r8), r4, r2)
47 /* One less waiter. If this was the last one needed wake
56 /* There are more threads to come. */
57 mov.l @(CURR_EVENT,r8), r6
59 /* Release the mutex. */
64 /* Wait for the remaining threads. The call will return immediately
65 if the CURR_EVENT memory has meanwhile been changed. */
71 mov.l @(PRIVATE,r8), r5
74 mov.l @(PRIVATE,r8), r0
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
87 mov.l @(CURR_EVENT,r8), r0
91 /* Increment LEFT. If this brings the count back to the
92 initial count unlock the object. */
94 mov.l @(INIT_COUNT,r8), r4
95 XADD (r3, @(LEFT,r8), r2, r5)
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)
110 cfi_adjust_cfa_offset (-4)
113 cfi_adjust_cfa_offset (-4)
116 cfi_adjust_cfa_offset (-4)
119 mov #0, r0 /* != PTHREAD_BARRIER_SERIAL_THREAD */
123 /* The necessary number of threads arrived. */
124 mov.l @(CURR_EVENT,r8), 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. */
137 mov.l @(PRIVATE,r8), r0
144 /* Increment LEFT. If this brings the count back to the
145 initial count unlock the object. */
147 mov.l @(INIT_COUNT,r8), r4
148 XADD (r3, @(LEFT,r8), r2, r5)
153 /* Release the mutex. */
154 DEC (@(MUTEX,r8), r2)
160 cfi_adjust_cfa_offset (-4)
163 cfi_adjust_cfa_offset (-4)
166 cfi_adjust_cfa_offset (-4)
169 mov #-1, r0 /* == PTHREAD_BARRIER_SERIAL_THREAD */
173 mov.l @(PRIVATE,r8), r6
187 mov.l @(PRIVATE,r8), r5
201 mov.l @(PRIVATE,r8), r5
215 mov.l @(PRIVATE,r8), r5
232 .long __lll_lock_wait-.Lwait0b
234 .long __lll_unlock_wake-.Lwake0b
236 .long __lll_unlock_wake-.Lwake1b
238 .long __lll_unlock_wake-.Lwake2b
239 .size pthread_barrier_wait,.-pthread_barrier_wait