]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
Update.
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_wait.S
CommitLineData
75fccede 1/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
0bc91edf
UD
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
893a3511
UD
641: movl broadcast_seq(%rdi), %edx
65 cmpl 4(%r8), %edx
66 jne 3f
67
68 incq wakeup_seq(%rdi)
0bc91edf 69
7abed170 70 incq woken_seq(%rdi)
0bc91edf 71
75fccede
UD
72 incl cond_futex(%rdi)
73
893a3511 743: LOCK
0bc91edf
UD
75#if cond_lock == 0
76 decl (%rdi)
77#else
78 decl cond_lock(%rdi)
79#endif
80 je 2f
81#if cond_lock != 0
82 addq $cond_lock, %rdi
83#endif
84 callq __lll_mutex_unlock_wake
85
24a49f38 86 /* Wake up all waiters to make sure no signal gets lost. */
75fccede 872: addq $cond_futex, %rdi
24a49f38
UD
88 movq $FUTEX_WAKE, %rsi
89 movl $0x7fffffff, %edx
90 movq $SYS_futex, %rax
91 syscall
92
5a03acfe 93 movq 16(%r8), %rdi
69431c9a 94 callq __pthread_mutex_cond_lock
0bc91edf 95
7661d9f7 96 retq
0bc91edf
UD
97 .size __condvar_cleanup, .-__condvar_cleanup
98
99
100/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
101 .globl __pthread_cond_wait
102 .type __pthread_cond_wait, @function
103 .align 16
104__pthread_cond_wait:
ad2be852 105.LSTARTCODE:
5a03acfe 106 pushq %r12
ad2be852 107.Lpush_r12:
893a3511
UD
108#define FRAME_SIZE 64
109 subq $FRAME_SIZE, %rsp
ad2be852 110.Lsubq:
7abed170
UD
111 /* Stack frame:
112
113 rsp + 64
114 +--------------------------+
115 rsp + 32 | cleanup buffer |
893a3511 116 +--------------------------+
7abed170
UD
117 rsp + 24 | old wake_seq value |
118 +--------------------------+
119 rsp + 16 | mutex pointer |
120 +--------------------------+
121 rsp + 8 | condvar pointer |
122 +--------------------------+
893a3511
UD
123 rsp + 4 | old broadcast_seq value |
124 +--------------------------+
7abed170
UD
125 rsp + 0 | old cancellation mode |
126 +--------------------------+
127 */
0bc91edf 128
e42a990e
UD
129 cmpq $-1, dep_mutex(%rdi)
130
131 /* Prepare structure passed to cancellation handler. */
0bc91edf
UD
132 movq %rdi, 8(%rsp)
133 movq %rsi, 16(%rsp)
134
e42a990e 135 je 15f
7661d9f7
UD
136 movq %rsi, dep_mutex(%rdi)
137
0bc91edf 138 /* Get internal lock. */
e42a990e 13915: movl $1, %esi
3a226d33 140 xorl %eax, %eax
0bc91edf
UD
141 LOCK
142#if cond_lock == 0
3a226d33 143 cmpxchgl %esi, (%rdi)
0bc91edf 144#else
3a226d33 145 cmpxchgl %esi, cond_lock(%rdi)
0bc91edf 146#endif
0bc91edf
UD
147 jne 1f
148
149 /* Unlock the mutex. */
7661d9f7 1502: movq 16(%rsp), %rdi
61623643
UD
151 xorq %rsi, %rsi
152 callq __pthread_mutex_unlock_usercnt
0bc91edf
UD
153
154 testl %eax, %eax
155 jne 12f
156
35e148cb 157 movq 8(%rsp), %rdi
7abed170 158 incq total_seq(%rdi)
75fccede 159 incl cond_futex(%rdi)
0bc91edf
UD
160
161 /* Install cancellation handler. */
162#ifdef PIC
5a03acfe 163 leaq __condvar_cleanup(%rip), %rsi
0bc91edf
UD
164#else
165 leaq __condvar_cleanup, %rsi
166#endif
167 leaq 32(%rsp), %rdi
168 movq %rsp, %rdx
169 callq __pthread_cleanup_push
170
171 /* Get and store current wakeup_seq value. */
172 movq 8(%rsp), %rdi
75fccede 173 movq wakeup_seq(%rdi), %r9
893a3511 174 movl broadcast_seq(%rdi), %edx
75fccede 175 movq %r9, 24(%rsp)
893a3511 176 movl %edx, 4(%rsp)
0bc91edf
UD
177
178 /* Unlock. */
75fccede
UD
1798: movl cond_futex(%rdi), %r12d
180 LOCK
0bc91edf
UD
181#if cond_lock == 0
182 decl (%rdi)
183#else
184 decl cond_lock(%rdi)
185#endif
186 jne 3f
187
69431c9a 1884: callq __pthread_enable_asynccancel
7661d9f7 189 movl %eax, (%rsp)
0bc91edf 190
32a589b1 191 movq 8(%rsp), %rdi
0bc91edf
UD
192 xorq %r10, %r10
193 movq %r12, %rdx
75fccede 194 addq $cond_futex-cond_lock, %rdi
0bc91edf 195 movq $SYS_futex, %rax
92ed3daf 196 movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */
0bc91edf 197 syscall
0bc91edf 198
7661d9f7 199 movl (%rsp), %edi
0bc91edf
UD
200 callq __pthread_disable_asynccancel
201
202 /* Lock. */
203 movq 8(%rsp), %rdi
204 movl $1, %esi
3a226d33 205 xorl %eax, %eax
0bc91edf
UD
206 LOCK
207#if cond_lock == 0
3a226d33 208 cmpxchgl %esi, (%rdi)
0bc91edf 209#else
3a226d33 210 cmpxchgl %esi, cond_lock(%rdi)
0bc91edf 211#endif
3a226d33 212 jnz 5f
0bc91edf 213
893a3511
UD
2146: movl broadcast_seq(%rdi), %edx
215
216 movq woken_seq(%rdi), %rax
0bc91edf 217
75fccede 218 movq wakeup_seq(%rdi), %r9
0bc91edf 219
893a3511
UD
220 cmpl 4(%rsp), %edx
221 jne 16f
222
75fccede 223 cmpq 24(%rsp), %r9
46a32546 224 jbe 8b
0bc91edf 225
75fccede 226 cmpq %rax, %r9
0bc91edf
UD
227 jna 8b
228
229 incq woken_seq(%rdi)
230
893a3511
UD
231 /* Unlock */
23216: LOCK
0bc91edf
UD
233#if cond_lock == 0
234 decl (%rdi)
235#else
236 decl cond_lock(%rdi)
237#endif
238 jne 10f
239
240 /* Remove cancellation handler. */
24111: movq 32+CLEANUP_PREV(%rsp), %rdx
35e148cb 242 movq %rdx, %fs:CLEANUP
0bc91edf
UD
243
244 movq 16(%rsp), %rdi
69431c9a 245 callq __pthread_mutex_cond_lock
893a3511 24614: addq $FRAME_SIZE, %rsp
ad2be852 247.Laddq:
0bc91edf
UD
248
249 popq %r12
ad2be852 250.Lpop_r12:
0bc91edf
UD
251
252 /* We return the result of the mutex_lock operation. */
253 retq
254
255 /* Initial locking failed. */
2561:
ad2be852 257.LSbl1:
0bc91edf
UD
258#if cond_lock != 0
259 addq $cond_lock, %rdi
260#endif
261 callq __lll_mutex_lock_wait
262 jmp 2b
263
893a3511 264 /* Unlock in loop requires wakeup. */
0bc91edf
UD
2653:
266#if cond_lock != 0
267 addq $cond_lock, %rdi
268#endif
269 callq __lll_mutex_unlock_wake
0bc91edf
UD
270 jmp 4b
271
272 /* Locking in loop failed. */
2735:
274#if cond_lock != 0
275 addq $cond_lock, %rdi
276#endif
6c477888 277 callq __lll_mutex_lock_wait
0bc91edf
UD
278#if cond_lock != 0
279 subq $cond_lock, %rdi
280#endif
281 jmp 6b
282
283 /* Unlock after loop requires wakeup. */
28410:
285#if cond_lock != 0
286 addq $cond_lock, %rdi
287#endif
288 callq __lll_mutex_unlock_wake
289 jmp 11b
290
291 /* The initial unlocking of the mutex failed. */
29212: movq %rax, %r10
293 movq 8(%rsp), %rdi
294 LOCK
295#if cond_lock == 0
296 decl (%rdi)
297#else
298 decl cond_lock(%rdi)
299#endif
300 jne 13f
301
302#if cond_lock != 0
303 addq $cond_lock, %rdi
304#endif
305 callq __lll_mutex_unlock_wake
306
30713: movq %r10, %rax
308 jmp 14b
ad2be852 309.LENDCODE:
0bc91edf
UD
310 .size __pthread_cond_wait, .-__pthread_cond_wait
311versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
312 GLIBC_2_3_2)
ad2be852
UD
313
314
315 .section .eh_frame,"a",@progbits
316.LSTARTFRAME:
39a46c42 317 .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
ad2be852 318.LSTARTCIE:
39a46c42
UD
319 .long 0 # CIE ID.
320 .byte 1 # Version number.
ad2be852 321#ifdef SHARED
39a46c42
UD
322 .string "zR" # NUL-terminated augmentation
323 # string.
ad2be852 324#else
39a46c42
UD
325 .ascii "\0" # NUL-terminated augmentation
326 # string.
ad2be852 327#endif
39a46c42
UD
328 .uleb128 1 # Code alignment factor.
329 .sleb128 -8 # Data alignment factor.
330 .byte 16 # Return address register
331 # column.
ad2be852 332#ifdef SHARED
39a46c42
UD
333 .uleb128 1 # Augmentation value length.
334 .byte 0x1b # Encoding: DW_EH_PE_pcrel
335 # + DW_EH_PE_sdata4.
ad2be852 336#endif
39a46c42 337 .byte 0x0c # DW_CFA_def_cfa
ad2be852
UD
338 .uleb128 7
339 .uleb128 8
39a46c42 340 .byte 0x90 # DW_CFA_offset, column 0x8
ad2be852
UD
341 .uleb128 1
342 .align 8
343.LENDCIE:
344
39a46c42 345 .long .LENDFDE-.LSTARTFDE # Length of the FDE.
ad2be852 346.LSTARTFDE:
39a46c42 347 .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
ad2be852 348#ifdef SHARED
39a46c42
UD
349 .long .LSTARTCODE-. # PC-relative start address
350 # of the code
ad2be852 351#else
39a46c42 352 .long .LSTARTCODE # Start address of the code.
ad2be852 353#endif
39a46c42 354 .long .LENDCODE-.LSTARTCODE # Length of the code.
ad2be852 355#ifdef SHARED
39a46c42 356 .uleb128 0 # No augmentation data.
ad2be852 357#endif
39a46c42
UD
358 .byte 0x40+.Lpush_r12-.LSTARTCODE # DW_CFA_advance_loc+N
359 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 360 .uleb128 16
39a46c42
UD
361 .byte 0x8c # DW_CFA_offset %r12
362 .uleb128 2
363 .byte 0x40+.Lsubq-.Lpush_r12 # DW_CFA_advance_loc+N
364 .byte 14 # DW_CFA_def_cfa_offset
893a3511 365 .uleb128 16+FRAME_SIZE
75fccede
UD
366 .byte 3 # DW_CFA_advance_loc2
367 .2byte .Laddq-.Lsubq
39a46c42 368 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 369 .uleb128 16
39a46c42
UD
370 .byte 0x40+.Lpop_r12-.Laddq # DW_CFA_advance_loc+N
371 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 372 .uleb128 8
39a46c42
UD
373 .byte 0xcc # DW_CFA_restore %r12
374 .byte 0x40+.LSbl1-.Lpop_r12 # DW_CFA_advance_loc+N
375 .byte 14 # DW_CFA_def_cfa_offset
ad2be852 376 .uleb128 80
39a46c42
UD
377 .byte 0x8c # DW_CFA_offset %r12
378 .uleb128 2
ad2be852
UD
379 .align 8
380.LENDFDE: