]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
Update.
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_signal.S
CommitLineData
d0aacb47
UD
1/* Copyright (C) 2002, 2003 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>
69431c9a 23#include <kernel-features.h>
d0aacb47
UD
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
69431c9a
UD
34#define FUTEX_REQUEUE 3
35
36#define EINVAL 22
d0aacb47
UD
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. */
7661d9f7 48 movq %rdi, %r8
d0aacb47
UD
49 movl $1, %esi
50 LOCK
51#if cond_lock == 0
7661d9f7 52 xaddl %esi, (%rdi)
d0aacb47 53#else
7661d9f7 54 xaddl %esi, cond_lock(%rdi)
d0aacb47
UD
55#endif
56 testl %esi, %esi
57 jne 1f
58
7661d9f7 592: addq $wakeup_seq, %rdi
69431c9a 60 movq total_seq(%r8), %rcx
d0aacb47
UD
61 cmpq (%rdi), %rcx
62 jbe 4f
63
64 /* Bump the wakeup number. */
65 addq $1, (%rdi)
66
67 /* Wake up one thread. */
7661d9f7 68 movq $FUTEX_REQUEUE, %rsi
d0aacb47 69 movq $SYS_futex, %rax
69431c9a
UD
70 xorq %rdx, %rdx
71 movq $1, %r10
d0aacb47
UD
72 syscall
73
69431c9a
UD
74#ifndef __ASSUME_FUTEX_REQUEUE
75 cmpq $-EINVAL, %rax
76 je 7f
77#endif
78
79 /* If we moved a thread we in any case have to make the syscall. */
80 testq %rax, %rax
81 jne 5f
82
d0aacb47
UD
83 /* Unlock. */
844: LOCK
7661d9f7
UD
85#if cond_lock == 0
86 decl (%r8)
87#else
69431c9a 88 decl cond_lock(%r8)
7661d9f7 89#endif
d0aacb47
UD
90 jne 5f
91
926: xorl %eax, %eax
93 retq
94
95 /* Initial locking failed. */
961:
97#if cond_lock != 0
98 addq $cond_lock, %rdi
99#endif
6c477888 100 callq __lll_mutex_lock_wait
d0aacb47
UD
101#if cond_lock != 0
102 subq $cond_lock, %rdi
103#endif
104 jmp 2b
105
7661d9f7 106 /* Unlock in loop requires wakeup. */
69431c9a
UD
1075:
108#if cond_lock != 0
109 addq $cond_lock-wakeup_seq, %rdi
110#else
111 movq %r8, %rdi
112#endif
6c477888 113 callq __lll_mutex_unlock_wake
d0aacb47 114 jmp 6b
69431c9a
UD
115
116#ifndef __ASSUME_FUTEX_REQUEUE
1177: /* The futex requeue functionality is not available. */
118 movq $1, %rdx
7661d9f7 119 movq $FUTEX_WAKE, %rsi
69431c9a
UD
120 movq $SYS_futex, %rax
121 syscall
122 jmp 4b
7661d9f7 123#endif
d0aacb47
UD
124 .size __pthread_cond_signal, .-__pthread_cond_signal
125versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
126 GLIBC_2_3_2)