]> sourceware.org Git - glibc.git/blame - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
Update.
[glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_wait.S
CommitLineData
0bc91edf
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>
23#include <tcb-offsets.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
35
36 .text
37
38 .align 16
39 .type __condvar_cleanup, @function
40 .globl __condvar_cleanup
41 .hidden __condvar_cleanup
42__condvar_cleanup:
43 /* Get internal lock. */
44 movq %rdi, %r8
5a03acfe 45 movq 8(%rdi), %rdi
0bc91edf 46 movl $1, %esi
3a226d33 47 xorl %eax, %eax
0bc91edf
UD
48 LOCK
49#if cond_lock == 0
3a226d33 50 cmpxchgl %esi, (%rdi)
0bc91edf 51#else
3a226d33 52 cmpxchgl %esi, cond_lock(%rdi)
0bc91edf 53#endif
3a226d33 54 jz 1f
0bc91edf
UD
55
56#if cond_lock != 0
57 addq $cond_lock, %rdi
58#endif
59 callq __lll_mutex_lock_wait
60#if cond_lock != 0
61 subq $cond_lock, %rdi
62#endif
63
7abed170 641: incq wakeup_seq(%rdi)
0bc91edf 65
7abed170 66 incq woken_seq(%rdi)
0bc91edf
UD
67
68 LOCK
69#if cond_lock == 0
70 decl (%rdi)
71#else
72 decl cond_lock(%rdi)
73#endif
74 je 2f
75#if cond_lock != 0
76 addq $cond_lock, %rdi
77#endif
78 callq __lll_mutex_unlock_wake
79
24a49f38
UD
80 /* Wake up all waiters to make sure no signal gets lost. */
812: addq $wakeup_seq, %rdi
82 movq $FUTEX_WAKE, %rsi
83 movl $0x7fffffff, %edx
84 movq $SYS_futex, %rax
85 syscall
86
5a03acfe 87 movq 16(%r8), %rdi
69431c9a 88 callq __pthread_mutex_cond_lock
0bc91edf 89
7661d9f7 90 retq
0bc91edf
UD
91 .size __condvar_cleanup, .-__condvar_cleanup
92
93
94/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
95 .globl __pthread_cond_wait
96 .type __pthread_cond_wait, @function
97 .align 16
98__pthread_cond_wait:
ad2be852 99.LSTARTCODE:
5a03acfe 100 pushq %r12
ad2be852 101.Lpush_r12:
0bc91edf 102 subq $64, %rsp
ad2be852 103.Lsubq:
7abed170
UD
104 /* Stack frame:
105
106 rsp + 64
107 +--------------------------+
108 rsp + 32 | cleanup buffer |
109 +--------------------------+
110 rsp + 24 | old wake_seq value |
111 +--------------------------+
112 rsp + 16 | mutex pointer |
113 +--------------------------+
114 rsp + 8 | condvar pointer |
115 +--------------------------+
116 rsp + 0 | old cancellation mode |
117 +--------------------------+
118 */
0bc91edf
UD
119
120 /* Prepare structure passed to cancellation handler. */
121 movq %rdi, 8(%rsp)
122 movq %rsi, 16(%rsp)
123
7661d9f7
UD
124 movq %rsi, dep_mutex(%rdi)
125
0bc91edf
UD
126 /* Get internal lock. */
127 movl $1, %esi
3a226d33 128 xorl %eax, %eax
0bc91edf
UD
129 LOCK
130#if cond_lock == 0
3a226d33 131 cmpxchgl %esi, (%rdi)
0bc91edf 132#else
3a226d33 133 cmpxchgl %esi, cond_lock(%rdi)
0bc91edf 134#endif
0bc91edf
UD
135 jne 1f
136
137 /* Unlock the mutex. */
7661d9f7 1382: movq 16(%rsp), %rdi
61623643
UD
139 xorq %rsi, %rsi
140 callq __pthread_mutex_unlock_usercnt
0bc91edf
UD
141
142 testl %eax, %eax
143 jne 12f
144
35e148cb 145 movq 8(%rsp), %rdi
7abed170 146 incq total_seq(%rdi)
0bc91edf
UD
147
148 /* Install cancellation handler. */
149#ifdef PIC
5a03acfe 150 leaq __condvar_cleanup(%rip), %rsi
0bc91edf
UD
151#else
152 leaq __condvar_cleanup, %rsi
153#endif
154 leaq 32(%rsp), %rdi
155 movq %rsp, %rdx
156 callq __pthread_cleanup_push
157
158 /* Get and store current wakeup_seq value. */
159 movq 8(%rsp), %rdi
160 movq wakeup_seq(%rdi), %r12
161 movq %r12, 24(%rsp)
162
163 /* Unlock. */
1648: LOCK
165#if cond_lock == 0
166 decl (%rdi)
167#else
168 decl cond_lock(%rdi)
169#endif
170 jne 3f
171
69431c9a 1724: callq __pthread_enable_asynccancel
7661d9f7 173 movl %eax, (%rsp)
0bc91edf 174
32a589b1 175 movq 8(%rsp), %rdi
0bc91edf
UD
176 xorq %r10, %r10
177 movq %r12, %rdx
178 addq $wakeup_seq-cond_lock, %rdi
179 movq $SYS_futex, %rax
92ed3daf 180 movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */
0bc91edf 181 syscall
0bc91edf 182
7661d9f7 183 movl (%rsp), %edi
0bc91edf
UD
184 callq __pthread_disable_asynccancel
185
186 /* Lock. */
187 movq 8(%rsp), %rdi
188 movl $1, %esi
3a226d33 189 xorl %eax, %eax
0bc91edf
UD
190 LOCK
191#if cond_lock == 0
3a226d33 192 cmpxchgl %esi, (%rdi)
0bc91edf 193#else
3a226d33 194 cmpxchgl %esi, cond_lock(%rdi)
0bc91edf 195#endif
3a226d33 196 jnz 5f
0bc91edf
UD
197
1986: movq woken_seq(%rdi), %rax
199
200 movq wakeup_seq(%rdi), %r12
201
46a32546
UD
202 cmpq 24(%rsp), %r12
203 jbe 8b
0bc91edf
UD
204
205 cmpq %rax, %r12
206 jna 8b
207
208 incq woken_seq(%rdi)
209
210 LOCK
211#if cond_lock == 0
212 decl (%rdi)
213#else
214 decl cond_lock(%rdi)
215#endif
216 jne 10f
217
218 /* Remove cancellation handler. */
21911: movq 32+CLEANUP_PREV(%rsp), %rdx
35e148cb 220 movq %rdx, %fs:CLEANUP
0bc91edf
UD
221
222 movq 16(%rsp), %rdi
69431c9a 223 callq __pthread_mutex_cond_lock
0bc91edf 22414: addq $64, %rsp
ad2be852 225.Laddq:
0bc91edf
UD
226
227 popq %r12
ad2be852 228.Lpop_r12:
0bc91edf
UD
229
230 /* We return the result of the mutex_lock operation. */
231 retq
232
233 /* Initial locking failed. */
2341:
ad2be852 235.LSbl1:
0bc91edf
UD
236#if cond_lock != 0
237 addq $cond_lock, %rdi
238#endif
239 callq __lll_mutex_lock_wait
240 jmp 2b
241
242 /* Unlock in loop requires waekup. */
2433:
244#if cond_lock != 0
245 addq $cond_lock, %rdi
246#endif
247 callq __lll_mutex_unlock_wake
0bc91edf
UD
248 jmp 4b
249
250 /* Locking in loop failed. */
2515:
252#if cond_lock != 0
253 addq $cond_lock, %rdi
254#endif
6c477888 255 callq __lll_mutex_lock_wait
0bc91edf
UD
256#if cond_lock != 0
257 subq $cond_lock, %rdi
258#endif
259 jmp 6b
260
261 /* Unlock after loop requires wakeup. */
26210:
263#if cond_lock != 0
264 addq $cond_lock, %rdi
265#endif
266 callq __lll_mutex_unlock_wake
267 jmp 11b
268
269 /* The initial unlocking of the mutex failed. */
27012: movq %rax, %r10
271 movq 8(%rsp), %rdi
272 LOCK
273#if cond_lock == 0
274 decl (%rdi)
275#else
276 decl cond_lock(%rdi)
277#endif
278 jne 13f
279
280#if cond_lock != 0
281 addq $cond_lock, %rdi
282#endif
283 callq __lll_mutex_unlock_wake
284
28513: movq %r10, %rax
286 jmp 14b
ad2be852 287.LENDCODE:
0bc91edf
UD
288 .size __pthread_cond_wait, .-__pthread_cond_wait
289versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
290 GLIBC_2_3_2)
ad2be852
UD
291
292
293 .section .eh_frame,"a",@progbits
294.LSTARTFRAME:
39a46c42 295 .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
ad2be852 296.LSTARTCIE:
39a46c42
UD
297 .long 0 # CIE ID.
298 .byte 1 # Version number.
ad2be852 299#ifdef SHARED
39a46c42
UD
300 .string "zR" # NUL-terminated augmentation
301 # string.
ad2be852 302#else
39a46c42
UD
303 .ascii "\0" # NUL-terminated augmentation
304 # string.
ad2be852 305#endif
39a46c42
UD
306 .uleb128 1 # Code alignment factor.
307 .sleb128 -8 # Data alignment factor.
308 .byte 16 # Return address register
309 # column.
ad2be852 310#ifdef SHARED
39a46c42
UD
311 .uleb128 1 # Augmentation value length.
312 .byte 0x1b # Encoding: DW_EH_PE_pcrel
313 # + DW_EH_PE_sdata4.
ad2be852 314#endif
39a46c42 315 .byte 0x0c # DW_CFA_def_cfa
ad2be852
UD
316 .uleb128 7
317 .uleb128 8
39a46c42 318 .byte 0x90 # DW_CFA_offset, column 0x8
ad2be852
UD
319 .uleb128 1
320 .align 8
321.LENDCIE:
322
39a46c42 323 .long .LENDFDE-.LSTARTFDE # Length of the FDE.
ad2be852 324.LSTARTFDE:
39a46c42 325 .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
ad2be852 326#ifdef SHARED
39a46c42
UD
327 .long .LSTARTCODE-. # PC-relative start address
328 # of the code
ad2be852 329#else
39a46c42 330 .long .LSTARTCODE # Start address of the code.
ad2be852 331#endif
39a46c42 332 .long .LENDCODE-.LSTARTCODE # Length of the code.
ad2be852 333#ifdef SHARED
39a46c42 334 .uleb128 0 # No augmentation data.
ad2be852 335#endif
39a46c42
UD
336 .byte 0x40+.Lpush_r12-.LSTARTCODE # DW_CFA_advance_loc+N
337 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 338 .uleb128 16
39a46c42
UD
339 .byte 0x8c # DW_CFA_offset %r12
340 .uleb128 2
341 .byte 0x40+.Lsubq-.Lpush_r12 # DW_CFA_advance_loc+N
342 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 343 .uleb128 80
18ddd3aa
UD
344 .byte 2 # DW_CFA_advance_loc1
345 .byte .Laddq-.Lsubq
39a46c42 346 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 347 .uleb128 16
39a46c42
UD
348 .byte 0x40+.Lpop_r12-.Laddq # DW_CFA_advance_loc+N
349 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 350 .uleb128 8
39a46c42
UD
351 .byte 0xcc # DW_CFA_restore %r12
352 .byte 0x40+.LSbl1-.Lpop_r12 # DW_CFA_advance_loc+N
353 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 354 .uleb128 80
39a46c42
UD
355 .byte 0x8c # DW_CFA_offset %r12
356 .uleb128 2
ad2be852
UD
357 .align 8
358.LENDFDE:
This page took 0.101809 seconds and 5 git commands to generate.