]> sourceware.org Git - glibc.git/blame - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
Update.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_broadcast.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_broadcast (pthread_cond_t *cond) */
42 .globl __pthread_cond_broadcast
43 .type __pthread_cond_broadcast, @function
44 .align 16
45__pthread_cond_broadcast:
46
47 /* Get internal lock. */
48 movl $1, %esi
3a226d33 49 xorl %eax, %eax
d0aacb47
UD
50 LOCK
51#if cond_lock == 0
3a226d33 52 cmpxchgl %esi, (%rdi)
d0aacb47 53#else
3a226d33 54 cmpxchgl %esi, cond_lock(%rdi)
d0aacb47 55#endif
3a226d33 56 jnz 1f
d0aacb47
UD
57
582: addq $wakeup_seq, %rdi
59 movq total_seq-wakeup_seq(%rdi), %rcx
60 cmpq (%rdi), %rcx
61 jna 4f
62
63 /* Cause all currently waiting threads to recognize they are
64 woken up. */
65 movq %rcx, (%rdi)
66
69431c9a
UD
67 /* Get the address of the mutex used. */
68 movq dep_mutex-wakeup_seq(%rdi), %r8
69
d0aacb47
UD
70 /* Unlock. */
71 LOCK
72 decl cond_lock-wakeup_seq(%rdi)
73 jne 7f
74
75 /* Wake up all threads. */
69431c9a 768: movq $FUTEX_REQUEUE, %rsi
d0aacb47 77 movq $SYS_futex, %rax
69431c9a
UD
78 movl $1, %edx
79 movq $0x7fffffff, %r10
d0aacb47
UD
80 syscall
81
69431c9a 82#ifndef __ASSUME_FUTEX_REQUEUE
91ceedb3 83 cmpq $-EINVAL, %rax
69431c9a
UD
84 je 9f
8510:
86#endif
87
d0aacb47
UD
88 xorl %eax, %eax
89 retq
90
91 .align 16
92 /* Unlock. */
934: LOCK
94 decl cond_lock-wakeup_seq(%rdi)
95 jne 5f
96
976: xorl %eax, %eax
98 retq
99
100 /* Initial locking failed. */
1011:
102#if cond_lock != 0
103 addq $cond_lock, %rdi
104#endif
6c477888 105 callq __lll_mutex_lock_wait
d0aacb47
UD
106#if cond_lock != 0
107 subq $cond_lock, %rdi
108#endif
109 jmp 2b
110
111 /* Unlock in loop requires waekup. */
1125: addq $cond_lock-wakeup_seq, %rdi
6c477888 113 callq __lll_mutex_unlock_wake
d0aacb47
UD
114 jmp 6b
115
116 /* Unlock in loop requires waekup. */
1177: addq $cond_lock-wakeup_seq, %rdi
6c477888 118 callq __lll_mutex_unlock_wake
d0aacb47
UD
119 subq $cond_lock-wakeup_seq, %rdi
120 jmp 8b
69431c9a
UD
121
122#ifndef __ASSUME_FUTEX_REQUEUE
1239: /* The futex requeue functionality is not available. */
124 movq $0x7fffffff, %rdx
125 movq $FUTEX_WAKE, %rsi
126 movq $SYS_futex, %rax
127 syscall
128 jmp 10b
129#endif
d0aacb47
UD
130 .size __pthread_cond_broadcast, .-__pthread_cond_broadcast
131versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
132 GLIBC_2_3_2)
This page took 0.07764 seconds and 5 git commands to generate.