]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_broadcast.S
1 /* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <sysdep.h>
21 #include <lowlevellock.h>
22 #include <lowlevelcond.h>
23 #include <bits/kernel-features.h>
24 #include <pthread-pi-defines.h>
25 #include <pthread-errnos.h>
26
27
28         .text
29
30         /* int pthread_cond_broadcast (pthread_cond_t *cond) */
31         .globl  __pthread_cond_broadcast
32         .type   __pthread_cond_broadcast, @function
33         .protected      __pthread_cond_broadcast
34         .align  16
35 __pthread_cond_broadcast:
36
37         /* Get internal lock.  */
38         movl    $1, %esi
39         xorl    %eax, %eax
40         LOCK
41 #if cond_lock == 0
42         cmpxchgl %esi, (%rdi)
43 #else
44         cmpxchgl %esi, cond_lock(%rdi)
45 #endif
46         jnz     1f
47
48 2:      addq    $cond_futex, %rdi
49         movq    total_seq-cond_futex(%rdi), %r9
50         cmpq    wakeup_seq-cond_futex(%rdi), %r9
51         jna     4f
52
53         /* Cause all currently waiting threads to recognize they are
54            woken up.  */
55         movq    %r9, wakeup_seq-cond_futex(%rdi)
56         movq    %r9, woken_seq-cond_futex(%rdi)
57         addq    %r9, %r9
58         movl    %r9d, (%rdi)
59         incl    broadcast_seq-cond_futex(%rdi)
60
61         /* Get the address of the mutex used.  */
62         movq    dep_mutex-cond_futex(%rdi), %r8
63
64         /* Unlock.  */
65         LOCK
66         decl    cond_lock-cond_futex(%rdi)
67         jne     7f
68
69 8:      cmpq    $-1, %r8
70         je      9f
71
72         /* Do not use requeue for pshared condvars.  */
73         testl   $PS_BIT, MUTEX_KIND(%r8)
74         jne     9f
75
76         /* Requeue to a PI mutex if the PI bit is set.  */
77         movl    MUTEX_KIND(%r8), %eax
78         andl    $(ROBUST_BIT|PI_BIT), %eax
79         cmpl    $PI_BIT, %eax
80         je      81f
81
82         /* Wake up all threads.  */
83 #ifdef __ASSUME_PRIVATE_FUTEX
84         movl    $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %esi
85 #else
86         movl    %fs:PRIVATE_FUTEX, %esi
87         orl     $FUTEX_CMP_REQUEUE, %esi
88 #endif
89         movl    $SYS_futex, %eax
90         movl    $1, %edx
91         movl    $0x7fffffff, %r10d
92         syscall
93
94         /* For any kind of error, which mainly is EAGAIN, we try again
95            with WAKE.  The general test also covers running on old
96            kernels.  */
97         cmpq    $-4095, %rax
98         jae     9f
99
100 10:     xorl    %eax, %eax
101         retq
102
103         /* Wake up all threads.  */
104 81:     movl    $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
105         movl    $SYS_futex, %eax
106         movl    $1, %edx
107         movl    $0x7fffffff, %r10d
108         syscall
109
110         /* For any kind of error, which mainly is EAGAIN, we try again
111            with WAKE.  The general test also covers running on old
112            kernels.  */
113         cmpq    $-4095, %rax
114         jb      10b
115         jmp     9f
116
117         .align  16
118         /* Unlock.  */
119 4:      LOCK
120         decl    cond_lock-cond_futex(%rdi)
121         jne     5f
122
123 6:      xorl    %eax, %eax
124         retq
125
126         /* Initial locking failed.  */
127 1:
128 #if cond_lock != 0
129         addq    $cond_lock, %rdi
130 #endif
131         cmpq    $-1, dep_mutex-cond_lock(%rdi)
132         movl    $LLL_PRIVATE, %eax
133         movl    $LLL_SHARED, %esi
134         cmovne  %eax, %esi
135         callq   __lll_lock_wait
136 #if cond_lock != 0
137         subq    $cond_lock, %rdi
138 #endif
139         jmp     2b
140
141         /* Unlock in loop requires wakeup.  */
142 5:      addq    $cond_lock-cond_futex, %rdi
143         cmpq    $-1, dep_mutex-cond_lock(%rdi)
144         movl    $LLL_PRIVATE, %eax
145         movl    $LLL_SHARED, %esi
146         cmovne  %eax, %esi
147         callq   __lll_unlock_wake
148         jmp     6b
149
150         /* Unlock in loop requires wakeup.  */
151 7:      addq    $cond_lock-cond_futex, %rdi
152         cmpq    $-1, %r8
153         movl    $LLL_PRIVATE, %eax
154         movl    $LLL_SHARED, %esi
155         cmovne  %eax, %esi
156         callq   __lll_unlock_wake
157         subq    $cond_lock-cond_futex, %rdi
158         jmp     8b
159
160 9:      /* The futex requeue functionality is not available.  */
161         cmpq    $-1, %r8
162         movl    $0x7fffffff, %edx
163 #ifdef __ASSUME_PRIVATE_FUTEX
164         movl    $FUTEX_WAKE, %eax
165         movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
166         cmove   %eax, %esi
167 #else
168         movl    $0, %eax
169         movl    %fs:PRIVATE_FUTEX, %esi
170         cmove   %eax, %esi
171         orl     $FUTEX_WAKE, %esi
172 #endif
173         movl    $SYS_futex, %eax
174         syscall
175         jmp     10b
176         .size   __pthread_cond_broadcast, .-__pthread_cond_broadcast
177 weak_alias(__pthread_cond_broadcast, pthread_cond_broadcast)