]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / x86_64 / pthread_barrier_wait.S
CommitLineData
b168057a 1/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
6a4263e3
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
6a4263e3
UD
18
19#include <sysdep.h>
e51deae7 20#include <lowlevellock.h>
6a4263e3
UD
21#include <lowlevelbarrier.h>
22
6a4263e3
UD
23
24 .text
25
26 .globl pthread_barrier_wait
27 .type pthread_barrier_wait,@function
28 .align 16
29pthread_barrier_wait:
30 /* Get the mutex. */
3a226d33
UD
31 xorl %eax, %eax
32 movl $1, %esi
6a4263e3 33 LOCK
3a226d33
UD
34 cmpxchgl %esi, MUTEX(%rdi)
35 jnz 1f
6a4263e3
UD
36
37 /* One less waiter. If this was the last one needed wake
38 everybody. */
392: decl LEFT(%rdi)
40 je 3f
41
42 /* There are more threads to come. */
43#if CURR_EVENT == 0
44 movl (%rdi), %edx
45#else
46 movl CURR_EVENT(%rdi), %edx
47#endif
48
49 /* Release the mutex. */
50 LOCK
3a226d33
UD
51 decl MUTEX(%rdi)
52 jne 6f
6a4263e3
UD
53
54 /* Wait for the remaining threads. The call will return immediately
55 if the CURR_EVENT memory has meanwhile been changed. */
ee618985
UD
567:
57#if FUTEX_WAIT == 0
d8ff3792 58 movl PRIVATE(%rdi), %esi
ee618985
UD
59#else
60 movl $FUTEX_WAIT, %esi
d8ff3792 61 orl PRIVATE(%rdi), %esi
ee618985 62#endif
6a4263e3 63 xorq %r10, %r10
ee618985 648: movl $SYS_futex, %eax
6a4263e3
UD
65 syscall
66
67 /* Don't return on spurious wakeups. The syscall does not change
68 any register except %eax so there is no need to reload any of
69 them. */
70#if CURR_EVENT == 0
71 cmpl %edx, (%rdi)
72#else
73 cmpl %edx, CURR_EVENT(%rdi)
74#endif
75 je 8b
76
37c054c7
UD
77 /* Increment LEFT. If this brings the count back to the
78 initial count unlock the object. */
79 movl $1, %edx
80 movl INIT_COUNT(%rdi), %eax
81 LOCK
82 xaddl %edx, LEFT(%rdi)
83 subl $1, %eax
84 cmpl %eax, %edx
85 jne,pt 10f
86
87 /* Release the mutex. We cannot release the lock before
88 waking the waiting threads since otherwise a new thread might
89 arrive and gets waken up, too. */
90 LOCK
91 decl MUTEX(%rdi)
92 jne 9f
93
9410: xorl %eax, %eax /* != PTHREAD_BARRIER_SERIAL_THREAD */
6a4263e3
UD
95
96 retq
97
98 /* The necessary number of threads arrived. */
37c054c7 993:
6a4263e3
UD
100#if CURR_EVENT == 0
101 incl (%rdi)
102#else
103 incl CURR_EVENT(%rdi)
104#endif
105
106 /* Wake up all waiters. The count is a signed number in the kernel
107 so 0x7fffffff is the highest value. */
108 movl $0x7fffffff, %edx
ee618985 109 movl $FUTEX_WAKE, %esi
d8ff3792 110 orl PRIVATE(%rdi), %esi
ee618985 111 movl $SYS_futex, %eax
6a4263e3
UD
112 syscall
113
37c054c7
UD
114 /* Increment LEFT. If this brings the count back to the
115 initial count unlock the object. */
116 movl $1, %edx
117 movl INIT_COUNT(%rdi), %eax
118 LOCK
119 xaddl %edx, LEFT(%rdi)
120 subl $1, %eax
121 cmpl %eax, %edx
122 jne,pt 5f
123
6a4263e3
UD
124 /* Release the mutex. We cannot release the lock before
125 waking the waiting threads since otherwise a new thread might
126 arrive and gets waken up, too. */
127 LOCK
3a226d33
UD
128 decl MUTEX(%rdi)
129 jne 4f
6a4263e3
UD
130
1315: orl $-1, %eax /* == PTHREAD_BARRIER_SERIAL_THREAD */
132
133 retq
134
e51deae7
UD
1351: movl PRIVATE(%rdi), %esi
136 addq $MUTEX, %rdi
137 xorl $LLL_SHARED, %esi
138 callq __lll_lock_wait
6a4263e3
UD
139 subq $MUTEX, %rdi
140 jmp 2b
141
e51deae7
UD
1424: movl PRIVATE(%rdi), %esi
143 addq $MUTEX, %rdi
144 xorl $LLL_SHARED, %esi
145 callq __lll_unlock_wake
6a4263e3
UD
146 jmp 5b
147
e51deae7
UD
1486: movl PRIVATE(%rdi), %esi
149 addq $MUTEX, %rdi
150 xorl $LLL_SHARED, %esi
151 callq __lll_unlock_wake
6a4263e3
UD
152 subq $MUTEX, %rdi
153 jmp 7b
37c054c7 154
e51deae7
UD
1559: movl PRIVATE(%rdi), %esi
156 addq $MUTEX, %rdi
157 xorl $LLL_SHARED, %esi
158 callq __lll_unlock_wake
37c054c7 159 jmp 10b
6a4263e3 160 .size pthread_barrier_wait,.-pthread_barrier_wait