]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_signal.S
1 /* Copyright (C) 2002-2005, 2007, 2009 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 <lowlevellock.h>
22 #include <lowlevelcond.h>
23 #include <pthread-pi-defines.h>
24 #include <bits/kernel-features.h>
25 #include <pthread-errnos.h>
26
27
28         .text
29
30         /* int pthread_cond_signal (pthread_cond_t *cond) */
31         .globl  __pthread_cond_signal
32         .type   __pthread_cond_signal, @function
33         .protected      __pthread_cond_signal
34         .align  16
35 __pthread_cond_signal:
36
37         /* Get internal lock.  */
38         movq    %rdi, %r8
39         movl    $1, %esi
40         xorl    %eax, %eax
41         LOCK
42 #if cond_lock == 0
43         cmpxchgl %esi, (%rdi)
44 #else
45         cmpxchgl %esi, cond_lock(%rdi)
46 #endif
47         jnz     1f
48
49 2:      addq    $cond_futex, %rdi
50         movq    total_seq(%r8), %rcx
51         cmpq    wakeup_seq(%r8), %rcx
52         jbe     4f
53
54         /* Bump the wakeup number.  */
55         addq    $1, wakeup_seq(%r8)
56         addl    $1, (%rdi)
57
58         /* Wake up one thread.  */
59         cmpq    $-1, dep_mutex(%r8)
60         movl    $FUTEX_WAKE_OP, %esi
61         movl    $1, %edx
62         movl    $SYS_futex, %eax
63         je      8f
64
65         /* Get the address of the mutex used.  */
66         movq    dep_mutex(%r8), %rcx
67         movl    MUTEX_KIND(%rcx), %r11d
68         andl    $(ROBUST_BIT|PI_BIT), %r11d
69         cmpl    $PI_BIT, %r11d
70         je      9f
71
72 #ifdef __ASSUME_PRIVATE_FUTEX
73         movl    $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
74 #else
75         orl     %fs:PRIVATE_FUTEX, %esi
76 #endif
77
78 8:      movl    $1, %r10d
79 #if cond_lock != 0
80         addq    $cond_lock, %r8
81 #endif
82         movl    $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d
83         syscall
84 #if cond_lock != 0
85         subq    $cond_lock, %r8
86 #endif
87         /* For any kind of error, we try again with WAKE.
88            The general test also covers running on old kernels.  */
89         cmpq    $-4095, %rax
90         jae     7f
91
92         xorl    %eax, %eax
93         retq
94
95         /* Wake up one thread and requeue none in the PI Mutex case.  */
96 9:      movl    $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
97         movq    %rcx, %r8
98         xorq    %r10, %r10
99         movl    (%rdi), %r9d    // XXX Can this be right?
100         syscall
101
102         leaq    -cond_futex(%rdi), %r8
103
104         /* For any kind of error, we try again with WAKE.
105            The general test also covers running on old kernels.  */
106         cmpq    $-4095, %rax
107         jb      4f
108
109 7:
110 #ifdef __ASSUME_PRIVATE_FUTEX
111         andl    $FUTEX_PRIVATE_FLAG, %esi
112 #else
113         andl    %fs:PRIVATE_FUTEX, %esi
114 #endif
115         orl     $FUTEX_WAKE, %esi
116         movl    $SYS_futex, %eax
117         /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
118         movl    $1, %edx  */
119         syscall
120
121         /* Unlock.  */
122 4:      LOCK
123 #if cond_lock == 0
124         decl    (%r8)
125 #else
126         decl    cond_lock(%r8)
127 #endif
128         jne     5f
129
130 6:      xorl    %eax, %eax
131         retq
132
133         /* Initial locking failed.  */
134 1:
135 #if cond_lock != 0
136         addq    $cond_lock, %rdi
137 #endif
138         cmpq    $-1, dep_mutex-cond_lock(%rdi)
139         movl    $LLL_PRIVATE, %eax
140         movl    $LLL_SHARED, %esi
141         cmovne  %eax, %esi
142         callq   __lll_lock_wait
143 #if cond_lock != 0
144         subq    $cond_lock, %rdi
145 #endif
146         jmp     2b
147
148         /* Unlock in loop requires wakeup.  */
149 5:
150         movq    %r8, %rdi
151 #if cond_lock != 0
152         addq    $cond_lock, %rdi
153 #endif
154         cmpq    $-1, dep_mutex-cond_lock(%rdi)
155         movl    $LLL_PRIVATE, %eax
156         movl    $LLL_SHARED, %esi
157         cmovne  %eax, %esi
158         callq   __lll_unlock_wake
159         jmp     6b
160         .size   __pthread_cond_signal, .-__pthread_cond_signal
161 weak_alias(__pthread_cond_signal, pthread_cond_signal)