]> git.ipfire.org Git - thirdparty/glibc.git/blob - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_signal.S
1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
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
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include <sysdep.h>
21 #include <shlib-compat.h>
22 #include <lowlevelcond.h>
23 #include <kernel-features.h>
24
25 #ifdef UP
26 # define LOCK
27 #else
28 # define LOCK lock
29 #endif
30
31 #define SYS_futex 202
32 #define FUTEX_WAIT 0
33 #define FUTEX_WAKE 1
34 #define FUTEX_REQUEUE 3
35
36 #define EINVAL 22
37
38
39 .text
40
41 /* int pthread_cond_signal (pthread_cond_t *cond) */
42 .globl __pthread_cond_signal
43 .type __pthread_cond_signal, @function
44 .align 16
45 __pthread_cond_signal:
46
47 /* Get internal lock. */
48 movq %rdi, %r8
49 movl $1, %esi
50 xorl %eax, %eax
51 LOCK
52 #if cond_lock == 0
53 cmpxchgl %esi, (%rdi)
54 #else
55 cmpxchgl %esi, cond_lock(%rdi)
56 #endif
57 jnz 1f
58
59 2: addq $cond_futex, %rdi
60 movq total_seq(%r8), %rcx
61 cmpq wakeup_seq(%r8), %rcx
62 jbe 4f
63
64 /* Bump the wakeup number. */
65 addq $1, wakeup_seq(%r8)
66 addl $1, (%rdi)
67
68 /* Wake up one thread. */
69 movq $FUTEX_WAKE, %rsi
70 movq $SYS_futex, %rax
71 movq $1, %rdx
72 syscall
73
74 /* Unlock. */
75 4: LOCK
76 #if cond_lock == 0
77 decl (%r8)
78 #else
79 decl cond_lock(%r8)
80 #endif
81 jne 5f
82
83 6: xorl %eax, %eax
84 retq
85
86 /* Initial locking failed. */
87 1:
88 #if cond_lock != 0
89 addq $cond_lock, %rdi
90 #endif
91 callq __lll_mutex_lock_wait
92 #if cond_lock != 0
93 subq $cond_lock, %rdi
94 #endif
95 jmp 2b
96
97 /* Unlock in loop requires wakeup. */
98 5:
99 movq %r8, %rdi
100 callq __lll_mutex_unlock_wake
101 jmp 6b
102 .size __pthread_cond_signal, .-__pthread_cond_signal
103 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
104 GLIBC_2_3_2)