]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_signal.S
CommitLineData
f7a9f785 1/* Copyright (C) 2002-2016 Free Software Foundation, Inc.
d0aacb47
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/>. */
d0aacb47
UD
18
19#include <sysdep.h>
20#include <shlib-compat.h>
e51deae7 21#include <lowlevellock.h>
d0aacb47 22#include <lowlevelcond.h>
42e69bcf 23#include <pthread-pi-defines.h>
69431c9a 24#include <kernel-features.h>
e51deae7 25#include <pthread-errnos.h>
5acf7263 26#include <stap-probe.h>
d0aacb47
UD
27
28
29 .text
30
31 /* int pthread_cond_signal (pthread_cond_t *cond) */
32 .globl __pthread_cond_signal
33 .type __pthread_cond_signal, @function
34 .align 16
35__pthread_cond_signal:
36
5acf7263
RM
37 LIBC_PROBE (cond_signal, 1, %rdi)
38
d0aacb47 39 /* Get internal lock. */
7661d9f7 40 movq %rdi, %r8
d0aacb47 41 movl $1, %esi
3a226d33 42 xorl %eax, %eax
d0aacb47
UD
43 LOCK
44#if cond_lock == 0
3a226d33 45 cmpxchgl %esi, (%rdi)
d0aacb47 46#else
3a226d33 47 cmpxchgl %esi, cond_lock(%rdi)
d0aacb47 48#endif
3a226d33 49 jnz 1f
d0aacb47 50
75fccede 512: addq $cond_futex, %rdi
69431c9a 52 movq total_seq(%r8), %rcx
75fccede 53 cmpq wakeup_seq(%r8), %rcx
d0aacb47
UD
54 jbe 4f
55
56 /* Bump the wakeup number. */
75fccede
UD
57 addq $1, wakeup_seq(%r8)
58 addl $1, (%rdi)
d0aacb47
UD
59
60 /* Wake up one thread. */
d9754f55 61 LP_OP(cmp) $-1, dep_mutex(%r8)
42e69bcf 62 movl $FUTEX_WAKE_OP, %esi
ee618985 63 movl $1, %edx
42e69bcf
UD
64 movl $SYS_futex, %eax
65 je 8f
66
67 /* Get the address of the mutex used. */
d9754f55 68 mov dep_mutex(%r8), %RCX_LP
ec492239
AS
69 movl MUTEX_KIND(%rcx), %r11d
70 andl $(ROBUST_BIT|PI_BIT), %r11d
71 cmpl $PI_BIT, %r11d
b0948ffd 72 je 9f
42e69bcf 73
5bd8a249 74#ifdef __ASSUME_PRIVATE_FUTEX
5bd8a249 75 movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
5bd8a249 76#else
42e69bcf 77 orl %fs:PRIVATE_FUTEX, %esi
5bd8a249 78#endif
42e69bcf
UD
79
808: movl $1, %r10d
a3615024
UD
81#if cond_lock != 0
82 addq $cond_lock, %r8
83#endif
84 movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
85 syscall
86#if cond_lock != 0
87 subq $cond_lock, %r8
88#endif
89 /* For any kind of error, we try again with WAKE.
90 The general test also covers running on old kernels. */
91 cmpq $-4095, %rax
92 jae 7f
93
94 xorl %eax, %eax
95 retq
96
42e69bcf
UD
97 /* Wake up one thread and requeue none in the PI Mutex case. */
989: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
99 movq %rcx, %r8
100 xorq %r10, %r10
101 movl (%rdi), %r9d // XXX Can this be right?
102 syscall
103
104 leaq -cond_futex(%rdi), %r8
105
106 /* For any kind of error, we try again with WAKE.
107 The general test also covers running on old kernels. */
108 cmpq $-4095, %rax
109 jb 4f
110
1117:
112#ifdef __ASSUME_PRIVATE_FUTEX
113 andl $FUTEX_PRIVATE_FLAG, %esi
114#else
115 andl %fs:PRIVATE_FUTEX, %esi
116#endif
117 orl $FUTEX_WAKE, %esi
a3615024
UD
118 movl $SYS_futex, %eax
119 /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
120 movl $1, %edx */
d0aacb47
UD
121 syscall
122
123 /* Unlock. */
1244: LOCK
7661d9f7
UD
125#if cond_lock == 0
126 decl (%r8)
127#else
69431c9a 128 decl cond_lock(%r8)
7661d9f7 129#endif
d0aacb47
UD
130 jne 5f
131
1326: xorl %eax, %eax
133 retq
134
135 /* Initial locking failed. */
1361:
137#if cond_lock != 0
138 addq $cond_lock, %rdi
139#endif
d9754f55 140 LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
5bd8a249 141 movl $LLL_PRIVATE, %eax
e51deae7 142 movl $LLL_SHARED, %esi
5bd8a249 143 cmovne %eax, %esi
e51deae7 144 callq __lll_lock_wait
d0aacb47
UD
145#if cond_lock != 0
146 subq $cond_lock, %rdi
147#endif
148 jmp 2b
149
7661d9f7 150 /* Unlock in loop requires wakeup. */
69431c9a 1515:
69431c9a 152 movq %r8, %rdi
5bd8a249
UD
153#if cond_lock != 0
154 addq $cond_lock, %rdi
155#endif
d9754f55 156 LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
5bd8a249 157 movl $LLL_PRIVATE, %eax
e51deae7 158 movl $LLL_SHARED, %esi
5bd8a249 159 cmovne %eax, %esi
e51deae7 160 callq __lll_unlock_wake
d0aacb47
UD
161 jmp 6b
162 .size __pthread_cond_signal, .-__pthread_cond_signal
163versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
164 GLIBC_2_3_2)