]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / i486 / pthread_cond_broadcast.S
CommitLineData
b168057a 1/* Copyright (C) 2002-2015 Free Software Foundation, Inc.
1d087a7e
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/>. */
1d087a7e
UD
18
19#include <sysdep.h>
20#include <shlib-compat.h>
e51deae7 21#include <lowlevellock.h>
1d087a7e 22#include <lowlevelcond.h>
69431c9a 23#include <kernel-features.h>
df47504c 24#include <pthread-pi-defines.h>
e51deae7 25#include <pthread-errnos.h>
17557282 26#include <stap-probe.h>
1d087a7e
UD
27
28 .text
29
30 /* int pthread_cond_broadcast (pthread_cond_t *cond) */
31 .globl __pthread_cond_broadcast
32 .type __pthread_cond_broadcast, @function
33 .align 16
34__pthread_cond_broadcast:
62605cbf 35 cfi_startproc
1d087a7e 36 pushl %ebx
62605cbf 37 cfi_adjust_cfa_offset(4)
dd7106b3 38 cfi_rel_offset(%ebx, 0)
69431c9a 39 pushl %esi
62605cbf 40 cfi_adjust_cfa_offset(4)
dd7106b3 41 cfi_rel_offset(%esi, 0)
69431c9a 42 pushl %edi
62605cbf 43 cfi_adjust_cfa_offset(4)
dd7106b3 44 cfi_rel_offset(%edi, 0)
75fccede 45 pushl %ebp
62605cbf 46 cfi_adjust_cfa_offset(4)
dd7106b3
DG
47 cfi_rel_offset(%ebp, 0)
48 cfi_remember_state
1d087a7e 49
75fccede 50 movl 20(%esp), %ebx
1d087a7e 51
17557282
RH
52 LIBC_PROBE (cond_broadcast, 1, %edx)
53
1d087a7e 54 /* Get internal lock. */
71451de2
UD
55 movl $1, %edx
56 xorl %eax, %eax
1d087a7e
UD
57 LOCK
58#if cond_lock == 0
71451de2 59 cmpxchgl %edx, (%ebx)
1d087a7e 60#else
71451de2 61 cmpxchgl %edx, cond_lock(%ebx)
1d087a7e 62#endif
3a226d33 63 jnz 1f
1d087a7e 64
75fccede
UD
652: addl $cond_futex, %ebx
66 movl total_seq+4-cond_futex(%ebx), %eax
67 movl total_seq-cond_futex(%ebx), %ebp
68 cmpl wakeup_seq+4-cond_futex(%ebx), %eax
1d087a7e
UD
69 ja 3f
70 jb 4f
75fccede 71 cmpl wakeup_seq-cond_futex(%ebx), %ebp
1d087a7e
UD
72 jna 4f
73
a1ea4c06
UD
74 /* Cause all currently waiting threads to recognize they are
75 woken up. */
75fccede
UD
763: movl %ebp, wakeup_seq-cond_futex(%ebx)
77 movl %eax, wakeup_seq-cond_futex+4(%ebx)
78 movl %ebp, woken_seq-cond_futex(%ebx)
79 movl %eax, woken_seq-cond_futex+4(%ebx)
80 addl %ebp, %ebp
81 addl $1, broadcast_seq-cond_futex(%ebx)
82 movl %ebp, (%ebx)
1d087a7e 83
69431c9a 84 /* Get the address of the mutex used. */
75fccede 85 movl dep_mutex-cond_futex(%ebx), %edi
69431c9a 86
567fb22a
UD
87 /* Unlock. */
88 LOCK
75fccede 89 subl $1, cond_lock-cond_futex(%ebx)
567fb22a
UD
90 jne 7f
91
e42a990e
UD
92 /* Don't use requeue for pshared condvars. */
938: cmpl $-1, %edi
94 je 9f
95
75956694
DG
96 /* Do not use requeue for pshared condvars. */
97 testl $PS_BIT, MUTEX_KIND(%edi)
df47504c
UD
98 jne 9f
99
75956694
DG
100 /* Requeue to a non-robust PI mutex if the PI bit is set and
101 the robust bit is not set. */
102 movl MUTEX_KIND(%edi), %eax
103 andl $(ROBUST_BIT|PI_BIT), %eax
104 cmpl $PI_BIT, %eax
105 je 81f
106
1d087a7e 107 /* Wake up all threads. */
22502ea2
UD
108#ifdef __ASSUME_PRIVATE_FUTEX
109 movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx
110#else
111 movl %gs:PRIVATE_FUTEX, %ecx
112 orl $FUTEX_CMP_REQUEUE, %ecx
113#endif
1d087a7e 114 movl $SYS_futex, %eax
69431c9a
UD
115 movl $0x7fffffff, %esi
116 movl $1, %edx
117 /* Get the address of the futex involved. */
118# if MUTEX_FUTEX != 0
119 addl $MUTEX_FUTEX, %edi
120# endif
75fccede
UD
121/* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for sysenter.
122 ENTER_KERNEL */
123 int $0x80
1d087a7e 124
75fccede
UD
125 /* For any kind of error, which mainly is EAGAIN, we try again
126 with WAKE. The general test also covers running on old
127 kernels. */
128 cmpl $0xfffff001, %eax
129 jae 9f
69431c9a 130
dd7106b3 1316: xorl %eax, %eax
75fccede 132 popl %ebp
62605cbf
UD
133 cfi_adjust_cfa_offset(-4)
134 cfi_restore(%ebp)
69431c9a 135 popl %edi
62605cbf
UD
136 cfi_adjust_cfa_offset(-4)
137 cfi_restore(%edi)
69431c9a 138 popl %esi
62605cbf
UD
139 cfi_adjust_cfa_offset(-4)
140 cfi_restore(%esi)
567fb22a 141 popl %ebx
62605cbf
UD
142 cfi_adjust_cfa_offset(-4)
143 cfi_restore(%ebx)
567fb22a
UD
144 ret
145
dd7106b3
DG
146 cfi_restore_state
147
75956694
DG
14881: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
149 movl $SYS_futex, %eax
150 movl $0x7fffffff, %esi
151 movl $1, %edx
152 /* Get the address of the futex involved. */
153# if MUTEX_FUTEX != 0
154 addl $MUTEX_FUTEX, %edi
155# endif
156 int $0x80
157
158 /* For any kind of error, which mainly is EAGAIN, we try again
159 with WAKE. The general test also covers running on old
160 kernels. */
161 cmpl $0xfffff001, %eax
162 jb 6b
163 jmp 9f
164
1d087a7e
UD
165 /* Initial locking failed. */
1661:
167#if cond_lock == 0
e51deae7 168 movl %ebx, %edx
1d087a7e 169#else
e51deae7 170 leal cond_lock(%ebx), %edx
1d087a7e 171#endif
22502ea2
UD
172#if (LLL_SHARED-LLL_PRIVATE) > 255
173 xorl %ecx, %ecx
174#endif
175 cmpl $-1, dep_mutex(%ebx)
176 setne %cl
177 subl $1, %ecx
178 andl $(LLL_SHARED-LLL_PRIVATE), %ecx
179#if LLL_PRIVATE != 0
180 addl $LLL_PRIVATE, %ecx
181#endif
e51deae7 182 call __lll_lock_wait
1d087a7e
UD
183 jmp 2b
184
dfedb126
UD
185 .align 16
186 /* Unlock. */
1874: LOCK
188 subl $1, cond_lock-cond_futex(%ebx)
189 je 6b
190
191 /* Unlock in loop requires wakeup. */
75fccede 1925: leal cond_lock-cond_futex(%ebx), %eax
22502ea2
UD
193#if (LLL_SHARED-LLL_PRIVATE) > 255
194 xorl %ecx, %ecx
195#endif
196 cmpl $-1, dep_mutex-cond_futex(%ebx)
197 setne %cl
198 subl $1, %ecx
199 andl $(LLL_SHARED-LLL_PRIVATE), %ecx
200#if LLL_PRIVATE != 0
201 addl $LLL_PRIVATE, %ecx
202#endif
e51deae7 203 call __lll_unlock_wake
1d087a7e 204 jmp 6b
567fb22a 205
dfedb126 206 /* Unlock in loop requires wakeup. */
75fccede 2077: leal cond_lock-cond_futex(%ebx), %eax
22502ea2
UD
208#if (LLL_SHARED-LLL_PRIVATE) > 255
209 xorl %ecx, %ecx
210#endif
211 cmpl $-1, dep_mutex-cond_futex(%ebx)
212 setne %cl
213 subl $1, %ecx
214 andl $(LLL_SHARED-LLL_PRIVATE), %ecx
215#if LLL_PRIVATE != 0
216 addl $LLL_PRIVATE, %ecx
217#endif
e51deae7 218 call __lll_unlock_wake
567fb22a 219 jmp 8b
69431c9a 220
69431c9a
UD
2219: /* The futex requeue functionality is not available. */
222 movl $0x7fffffff, %edx
22502ea2
UD
223#if FUTEX_PRIVATE_FLAG > 255
224 xorl %ecx, %ecx
225#endif
226 cmpl $-1, dep_mutex-cond_futex(%ebx)
227 sete %cl
228 subl $1, %ecx
229#ifdef __ASSUME_PRIVATE_FUTEX
230 andl $FUTEX_PRIVATE_FLAG, %ecx
231#else
232 andl %gs:PRIVATE_FUTEX, %ecx
233#endif
234 addl $FUTEX_WAKE, %ecx
69431c9a
UD
235 movl $SYS_futex, %eax
236 ENTER_KERNEL
dd7106b3 237 jmp 6b
62605cbf 238 cfi_endproc
1d087a7e
UD
239 .size __pthread_cond_broadcast, .-__pthread_cond_broadcast
240versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
241 GLIBC_2_3_2)