Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_signal.S
blob0e8fe0c0f371e8e856dac8b5ba78e52ae1e816ad
1 /* Copyright (C) 2002-2015 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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.
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.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
19 #include <sysdep.h>
20 #include <shlib-compat.h>
21 #include <lowlevellock.h>
22 #include <lowlevelcond.h>
23 #include <pthread-pi-defines.h>
24 #include <kernel-features.h>
25 #include <pthread-errnos.h>
26 #include <stap-probe.h>
29         .text
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:
37         LIBC_PROBE (cond_signal, 1, %rdi)
39         /* Get internal lock.  */
40         movq    %rdi, %r8
41         movl    $1, %esi
42         xorl    %eax, %eax
43         LOCK
44 #if cond_lock == 0
45         cmpxchgl %esi, (%rdi)
46 #else
47         cmpxchgl %esi, cond_lock(%rdi)
48 #endif
49         jnz     1f
51 2:      addq    $cond_futex, %rdi
52         movq    total_seq(%r8), %rcx
53         cmpq    wakeup_seq(%r8), %rcx
54         jbe     4f
56         /* Bump the wakeup number.  */
57         addq    $1, wakeup_seq(%r8)
58         addl    $1, (%rdi)
60         /* Wake up one thread.  */
61         LP_OP(cmp) $-1, dep_mutex(%r8)
62         movl    $FUTEX_WAKE_OP, %esi
63         movl    $1, %edx
64         movl    $SYS_futex, %eax
65         je      8f
67         /* Get the address of the mutex used.  */
68         mov     dep_mutex(%r8), %RCX_LP
69         movl    MUTEX_KIND(%rcx), %r11d
70         andl    $(ROBUST_BIT|PI_BIT), %r11d
71         cmpl    $PI_BIT, %r11d
72         je      9f
74 #ifdef __ASSUME_PRIVATE_FUTEX
75         movl    $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
76 #else
77         orl     %fs:PRIVATE_FUTEX, %esi
78 #endif
80 8:      movl    $1, %r10d
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
94         xorl    %eax, %eax
95         retq
97         /* Wake up one thread and requeue none in the PI Mutex case.  */
98 9:      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
104         leaq    -cond_futex(%rdi), %r8
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
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
118         movl    $SYS_futex, %eax
119         /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
120         movl    $1, %edx  */
121         syscall
123         /* Unlock.  */
124 4:      LOCK
125 #if cond_lock == 0
126         decl    (%r8)
127 #else
128         decl    cond_lock(%r8)
129 #endif
130         jne     5f
132 6:      xorl    %eax, %eax
133         retq
135         /* Initial locking failed.  */
137 #if cond_lock != 0
138         addq    $cond_lock, %rdi
139 #endif
140         LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
141         movl    $LLL_PRIVATE, %eax
142         movl    $LLL_SHARED, %esi
143         cmovne  %eax, %esi
144         callq   __lll_lock_wait
145 #if cond_lock != 0
146         subq    $cond_lock, %rdi
147 #endif
148         jmp     2b
150         /* Unlock in loop requires wakeup.  */
152         movq    %r8, %rdi
153 #if cond_lock != 0
154         addq    $cond_lock, %rdi
155 #endif
156         LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
157         movl    $LLL_PRIVATE, %eax
158         movl    $LLL_SHARED, %esi
159         cmovne  %eax, %esi
160         callq   __lll_unlock_wake
161         jmp     6b
162         .size   __pthread_cond_signal, .-__pthread_cond_signal
163 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
164                   GLIBC_2_3_2)