]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / nptl / sysdeps / unix / sysv / linux / x86_64 / pthread_cond_timedwait.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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <sysdep.h>
20 #include <lowlevellock.h>
21 #include <lowlevelcond.h>
22 #include <pthread-pi-defines.h>
23 #include <pthread-errnos.h>
24 #include <bits/kernel-features.h>
25 #include <tcb-offsets.h>
26
27 /* For the calculation see asm/vsyscall.h.  */
28 #define VSYSCALL_ADDR_vgettimeofday     0xffffffffff600000
29
30
31         .text
32
33
34 /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
35                                const struct timespec *abstime)  */
36         .globl  __pthread_cond_timedwait
37         .type   __pthread_cond_timedwait, @function
38         .protected      __pthread_cond_timedwait
39         .align  16
40 __pthread_cond_timedwait:
41 .LSTARTCODE:
42         cfi_startproc
43
44         pushq   %r12
45         cfi_adjust_cfa_offset(8)
46         cfi_rel_offset(%r12, 0)
47         pushq   %r13
48         cfi_adjust_cfa_offset(8)
49         cfi_rel_offset(%r13, 0)
50         pushq   %r14
51         cfi_adjust_cfa_offset(8)
52         cfi_rel_offset(%r14, 0)
53         pushq   %r15
54         cfi_adjust_cfa_offset(8)
55         cfi_rel_offset(%r15, 0)
56 #ifdef __ASSUME_FUTEX_CLOCK_REALTIME
57 # define FRAME_SIZE 32
58 #else
59 # define FRAME_SIZE 48
60 #endif
61         subq    $FRAME_SIZE, %rsp
62         cfi_adjust_cfa_offset(FRAME_SIZE)
63         cfi_remember_state
64
65         cmpq    $1000000000, 8(%rdx)
66         movl    $EINVAL, %eax
67         jae     48f
68
69         /* Stack frame:
70
71            rsp + 48
72                     +--------------------------+
73            rsp + 32 | timeout value            |
74                     +--------------------------+
75            rsp + 24 | old wake_seq value       |
76                     +--------------------------+
77            rsp + 16 | mutex pointer            |
78                     +--------------------------+
79            rsp +  8 | condvar pointer          |
80                     +--------------------------+
81            rsp +  4 | old broadcast_seq value  |
82                     +--------------------------+
83            rsp +  0 | old cancellation mode    |
84                     +--------------------------+
85         */
86
87         cmpq    $-1, dep_mutex(%rdi)
88
89         /* Prepare structure passed to cancellation handler.  */
90         movq    %rdi, 8(%rsp)
91         movq    %rsi, 16(%rsp)
92         movq    %rdx, %r13
93
94         je      22f
95         movq    %rsi, dep_mutex(%rdi)
96
97 22:
98 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
99 #  ifdef __PIC__
100         cmpl    $0, __have_futex_clock_realtime@GOTOFF(%rip)
101 #  else
102         cmpl    $0, __have_futex_clock_realtime
103 #  endif
104         je      .Lreltmo
105 #endif
106
107         /* Get internal lock.  */
108         movl    $1, %esi
109         xorl    %eax, %eax
110         LOCK
111 #if cond_lock == 0
112         cmpxchgl %esi, (%rdi)
113 #else
114         cmpxchgl %esi, cond_lock(%rdi)
115 #endif
116         jnz     31f
117
118         /* Unlock the mutex.  */
119 32:     movq    16(%rsp), %rdi
120         xorl    %esi, %esi
121         callq   __pthread_mutex_unlock_usercnt
122
123         testl   %eax, %eax
124         jne     46f
125
126         movq    8(%rsp), %rdi
127         incq    total_seq(%rdi)
128         incl    cond_futex(%rdi)
129         addl    $(1 << nwaiters_shift), cond_nwaiters(%rdi)
130
131         /* Get and store current wakeup_seq value.  */
132         movq    8(%rsp), %rdi
133         movq    wakeup_seq(%rdi), %r9
134         movl    broadcast_seq(%rdi), %edx
135         movq    %r9, 24(%rsp)
136         movl    %edx, 4(%rsp)
137
138 38:     movl    cond_futex(%rdi), %r12d
139
140         /* Unlock.  */
141         LOCK
142 #if cond_lock == 0
143         decl    (%rdi)
144 #else
145         decl    cond_lock(%rdi)
146 #endif
147         jne     33f
148
149 .LcleanupSTART1:
150 34:     callq   __pthread_enable_asynccancel
151         movl    %eax, (%rsp)
152
153         movq    %r13, %r10
154         movl    $FUTEX_WAIT_BITSET, %esi
155         cmpq    $-1, dep_mutex(%rdi)
156         je      60f
157
158         movq    dep_mutex(%rdi), %r8
159         /* Requeue to a non-robust PI mutex if the PI bit is set and
160         the robust bit is not set.  */
161         movl    MUTEX_KIND(%r8), %eax
162         andl    $(ROBUST_BIT|PI_BIT), %eax
163         cmpl    $PI_BIT, %eax
164         jne     61f
165
166         movl    $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
167         xorl    %eax, %eax
168         /* The following only works like this because we only support
169            two clocks, represented using a single bit.  */
170         testl   $1, cond_nwaiters(%rdi)
171         movl    $FUTEX_CLOCK_REALTIME, %edx
172         cmove   %edx, %eax
173         orl     %eax, %esi
174         movq    %r12, %rdx
175         addq    $cond_futex, %rdi
176         movl    $SYS_futex, %eax
177         syscall
178
179         movl    $1, %r15d
180 #ifdef __ASSUME_REQUEUE_PI
181         jmp     62f
182 #else
183         cmpq    $-4095, %rax
184         jnae    62f
185
186         subq    $cond_futex, %rdi
187 #endif
188
189 61:     movl    $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
190 60:     xorl    %r15d, %r15d
191         xorl    %eax, %eax
192         /* The following only works like this because we only support
193            two clocks, represented using a single bit.  */
194         testl   $1, cond_nwaiters(%rdi)
195         movl    $FUTEX_CLOCK_REALTIME, %edx
196         movl    $0xffffffff, %r9d
197         cmove   %edx, %eax
198         orl     %eax, %esi
199         movq    %r12, %rdx
200         addq    $cond_futex, %rdi
201         movl    $SYS_futex, %eax
202         syscall
203 62:     movq    %rax, %r14
204
205         movl    (%rsp), %edi
206         callq   __pthread_disable_asynccancel
207 .LcleanupEND1:
208
209         /* Lock.  */
210         movq    8(%rsp), %rdi
211         movl    $1, %esi
212         xorl    %eax, %eax
213         LOCK
214 #if cond_lock == 0
215         cmpxchgl %esi, (%rdi)
216 #else
217         cmpxchgl %esi, cond_lock(%rdi)
218 #endif
219         jne     35f
220
221 36:     movl    broadcast_seq(%rdi), %edx
222
223         movq    woken_seq(%rdi), %rax
224
225         movq    wakeup_seq(%rdi), %r9
226
227         cmpl    4(%rsp), %edx
228         jne     53f
229
230         cmpq    24(%rsp), %r9
231         jbe     45f
232
233         cmpq    %rax, %r9
234         ja      39f
235
236 45:     cmpq    $-ETIMEDOUT, %r14
237         jne     38b
238
239 99:     incq    wakeup_seq(%rdi)
240         incl    cond_futex(%rdi)
241         movl    $ETIMEDOUT, %r14d
242         jmp     44f
243
244 53:     xorq    %r14, %r14
245         jmp     54f
246
247 39:     xorq    %r14, %r14
248 44:     incq    woken_seq(%rdi)
249
250 54:     subl    $(1 << nwaiters_shift), cond_nwaiters(%rdi)
251
252         /* Wake up a thread which wants to destroy the condvar object.  */
253         cmpq    $0xffffffffffffffff, total_seq(%rdi)
254         jne     55f
255         movl    cond_nwaiters(%rdi), %eax
256         andl    $~((1 << nwaiters_shift) - 1), %eax
257         jne     55f
258
259         addq    $cond_nwaiters, %rdi
260         cmpq    $-1, dep_mutex-cond_nwaiters(%rdi)
261         movl    $1, %edx
262 #ifdef __ASSUME_PRIVATE_FUTEX
263         movl    $FUTEX_WAKE, %eax
264         movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
265         cmove   %eax, %esi
266 #else
267         movl    $0, %eax
268         movl    %fs:PRIVATE_FUTEX, %esi
269         cmove   %eax, %esi
270         orl     $FUTEX_WAKE, %esi
271 #endif
272         movl    $SYS_futex, %eax
273         syscall
274         subq    $cond_nwaiters, %rdi
275
276 55:     LOCK
277 #if cond_lock == 0
278         decl    (%rdi)
279 #else
280         decl    cond_lock(%rdi)
281 #endif
282         jne     40f
283
284         /* If requeue_pi is used the kernel performs the locking of the
285            mutex. */
286 41:     movq    16(%rsp), %rdi
287         testl   %r15d, %r15d
288         jnz     64f
289
290         callq   __pthread_mutex_cond_lock
291
292 63:     testq   %rax, %rax
293         cmoveq  %r14, %rax
294
295 48:     addq    $FRAME_SIZE, %rsp
296         cfi_adjust_cfa_offset(-FRAME_SIZE)
297         popq    %r15
298         cfi_adjust_cfa_offset(-8)
299         cfi_restore(%r15)
300         popq    %r14
301         cfi_adjust_cfa_offset(-8)
302         cfi_restore(%r14)
303         popq    %r13
304         cfi_adjust_cfa_offset(-8)
305         cfi_restore(%r13)
306         popq    %r12
307         cfi_adjust_cfa_offset(-8)
308         cfi_restore(%r12)
309
310         retq
311
312         cfi_restore_state
313
314 64:     callq   __pthread_mutex_cond_lock_adjust
315         movq    %r14, %rax
316         jmp     48b
317
318         /* Initial locking failed.  */
319 31:
320 #if cond_lock != 0
321         addq    $cond_lock, %rdi
322 #endif
323         cmpq    $-1, dep_mutex-cond_lock(%rdi)
324         movl    $LLL_PRIVATE, %eax
325         movl    $LLL_SHARED, %esi
326         cmovne  %eax, %esi
327         callq   __lll_lock_wait
328         jmp     32b
329
330         /* Unlock in loop requires wakeup.  */
331 33:
332 #if cond_lock != 0
333         addq    $cond_lock, %rdi
334 #endif
335         cmpq    $-1, dep_mutex-cond_lock(%rdi)
336         movl    $LLL_PRIVATE, %eax
337         movl    $LLL_SHARED, %esi
338         cmovne  %eax, %esi
339         callq   __lll_unlock_wake
340         jmp     34b
341
342         /* Locking in loop failed.  */
343 35:
344 #if cond_lock != 0
345         addq    $cond_lock, %rdi
346 #endif
347         cmpq    $-1, dep_mutex-cond_lock(%rdi)
348         movl    $LLL_PRIVATE, %eax
349         movl    $LLL_SHARED, %esi
350         cmovne  %eax, %esi
351         callq   __lll_lock_wait
352 #if cond_lock != 0
353         subq    $cond_lock, %rdi
354 #endif
355         jmp     36b
356
357         /* Unlock after loop requires wakeup.  */
358 40:
359 #if cond_lock != 0
360         addq    $cond_lock, %rdi
361 #endif
362         cmpq    $-1, dep_mutex-cond_lock(%rdi)
363         movl    $LLL_PRIVATE, %eax
364         movl    $LLL_SHARED, %esi
365         cmovne  %eax, %esi
366         callq   __lll_unlock_wake
367         jmp     41b
368
369         /* The initial unlocking of the mutex failed.  */
370 46:     movq    8(%rsp), %rdi
371         movq    %rax, (%rsp)
372         LOCK
373 #if cond_lock == 0
374         decl    (%rdi)
375 #else
376         decl    cond_lock(%rdi)
377 #endif
378         jne     47f
379
380 #if cond_lock != 0
381         addq    $cond_lock, %rdi
382 #endif
383         cmpq    $-1, dep_mutex-cond_lock(%rdi)
384         movl    $LLL_PRIVATE, %eax
385         movl    $LLL_SHARED, %esi
386         cmovne  %eax, %esi
387         callq   __lll_unlock_wake
388
389 47:     movq    (%rsp), %rax
390         jmp     48b
391
392
393 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
394 .Lreltmo:
395         xorl    %r15d, %r15d
396
397         /* Get internal lock.  */
398         movl    $1, %esi
399         xorl    %eax, %eax
400         LOCK
401 # if cond_lock == 0
402         cmpxchgl %esi, (%rdi)
403 # else
404         cmpxchgl %esi, cond_lock(%rdi)
405 # endif
406         jnz     1f
407
408         /* Unlock the mutex.  */
409 2:      movq    16(%rsp), %rdi
410         xorl    %esi, %esi
411         callq   __pthread_mutex_unlock_usercnt
412
413         testl   %eax, %eax
414         jne     46b
415
416         movq    8(%rsp), %rdi
417         incq    total_seq(%rdi)
418         incl    cond_futex(%rdi)
419         addl    $(1 << nwaiters_shift), cond_nwaiters(%rdi)
420
421         /* Get and store current wakeup_seq value.  */
422         movq    8(%rsp), %rdi
423         movq    wakeup_seq(%rdi), %r9
424         movl    broadcast_seq(%rdi), %edx
425         movq    %r9, 24(%rsp)
426         movl    %edx, 4(%rsp)
427
428         /* Get the current time.  */
429 8:
430 # ifdef __NR_clock_gettime
431         /* Get the clock number.  Note that the field in the condvar
432            structure stores the number minus 1.  */
433         movq    8(%rsp), %rdi
434         movl    cond_nwaiters(%rdi), %edi
435         andl    $((1 << nwaiters_shift) - 1), %edi
436         /* Only clocks 0 and 1 are allowed so far.  Both are handled in the
437            kernel.  */
438         leaq    32(%rsp), %rsi
439 26:     movl    $__NR_clock_gettime, %eax
440         syscall
441 27:
442 #  ifndef __ASSUME_POSIX_TIMERS
443         cmpq    $-ENOSYS, %rax
444         je      19f
445 #  endif
446
447         /* Compute relative timeout.  */
448         movq    (%r13), %rcx
449         movq    8(%r13), %rdx
450         subq    32(%rsp), %rcx
451         subq    40(%rsp), %rdx
452 # else
453         leaq    24(%rsp), %rdi
454         xorl    %esi, %esi
455         movq    $VSYSCALL_ADDR_vgettimeofday, %rax
456         callq   *%rax
457
458         /* Compute relative timeout.  */
459         movq    40(%rsp), %rax
460         movl    $1000, %edx
461         mul     %rdx            /* Milli seconds to nano seconds.  */
462         movq    (%r13), %rcx
463         movq    8(%r13), %rdx
464         subq    32(%rsp), %rcx
465         subq    %rax, %rdx
466 # endif
467         jns     12f
468         addq    $1000000000, %rdx
469         decq    %rcx
470 12:     testq   %rcx, %rcx
471         movq    8(%rsp), %rdi
472         movq    $-ETIMEDOUT, %r14
473         js      6f
474
475         /* Store relative timeout.  */
476 21:     movq    %rcx, 32(%rsp)
477         movq    %rdx, 40(%rsp)
478
479         movl    cond_futex(%rdi), %r12d
480
481         /* Unlock.  */
482         LOCK
483 # if cond_lock == 0
484         decl    (%rdi)
485 # else
486         decl    cond_lock(%rdi)
487 # endif
488         jne     3f
489
490 .LcleanupSTART2:
491 4:      callq   __pthread_enable_asynccancel
492         movl    %eax, (%rsp)
493
494         leaq    32(%rsp), %r10
495         cmpq    $-1, dep_mutex(%rdi)
496         movq    %r12, %rdx
497 # ifdef __ASSUME_PRIVATE_FUTEX
498         movl    $FUTEX_WAIT, %eax
499         movl    $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
500         cmove   %eax, %esi
501 # else
502         movl    $0, %eax
503         movl    %fs:PRIVATE_FUTEX, %esi
504         cmove   %eax, %esi
505 #  if FUTEX_WAIT != 0
506         orl     $FUTEX_WAIT, %esi
507 #  endif
508 # endif
509         addq    $cond_futex, %rdi
510         movl    $SYS_futex, %eax
511         syscall
512         movq    %rax, %r14
513
514         movl    (%rsp), %edi
515         callq   __pthread_disable_asynccancel
516 .LcleanupEND2:
517
518         /* Lock.  */
519         movq    8(%rsp), %rdi
520         movl    $1, %esi
521         xorl    %eax, %eax
522         LOCK
523 # if cond_lock == 0
524         cmpxchgl %esi, (%rdi)
525 # else
526         cmpxchgl %esi, cond_lock(%rdi)
527 # endif
528         jne     5f
529
530 6:      movl    broadcast_seq(%rdi), %edx
531
532         movq    woken_seq(%rdi), %rax
533
534         movq    wakeup_seq(%rdi), %r9
535
536         cmpl    4(%rsp), %edx
537         jne     53b
538
539         cmpq    24(%rsp), %r9
540         jbe     15f
541
542         cmpq    %rax, %r9
543         ja      39b
544
545 15:     cmpq    $-ETIMEDOUT, %r14
546         jne     8b
547
548         jmp     99b
549
550         /* Initial locking failed.  */
551 1:
552 # if cond_lock != 0
553         addq    $cond_lock, %rdi
554 # endif
555         cmpq    $-1, dep_mutex-cond_lock(%rdi)
556         movl    $LLL_PRIVATE, %eax
557         movl    $LLL_SHARED, %esi
558         cmovne  %eax, %esi
559         callq   __lll_lock_wait
560         jmp     2b
561
562         /* Unlock in loop requires wakeup.  */
563 3:
564 # if cond_lock != 0
565         addq    $cond_lock, %rdi
566 # endif
567         cmpq    $-1, dep_mutex-cond_lock(%rdi)
568         movl    $LLL_PRIVATE, %eax
569         movl    $LLL_SHARED, %esi
570         cmovne  %eax, %esi
571         callq   __lll_unlock_wake
572         jmp     4b
573
574         /* Locking in loop failed.  */
575 5:
576 # if cond_lock != 0
577         addq    $cond_lock, %rdi
578 # endif
579         cmpq    $-1, dep_mutex-cond_lock(%rdi)
580         movl    $LLL_PRIVATE, %eax
581         movl    $LLL_SHARED, %esi
582         cmovne  %eax, %esi
583         callq   __lll_lock_wait
584 # if cond_lock != 0
585         subq    $cond_lock, %rdi
586 # endif
587         jmp     6b
588
589 # if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
590         /* clock_gettime not available.  */
591 19:     leaq    32(%rsp), %rdi
592         xorl    %esi, %esi
593         movq    $VSYSCALL_ADDR_vgettimeofday, %rax
594         callq   *%rax
595
596         /* Compute relative timeout.  */
597         movq    40(%rsp), %rax
598         movl    $1000, %edx
599         mul     %rdx            /* Milli seconds to nano seconds.  */
600         movq    (%r13), %rcx
601         movq    8(%r13), %rdx
602         subq    32(%rsp), %rcx
603         subq    %rax, %rdx
604         jns     20f
605         addq    $1000000000, %rdx
606         decq    %rcx
607 20:     testq   %rcx, %rcx
608         movq    8(%rsp), %rdi
609         movq    $-ETIMEDOUT, %r14
610         js      6b
611         jmp     21b
612 # endif
613 #endif
614         .size   __pthread_cond_timedwait, .-__pthread_cond_timedwait
615 weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)
616
617
618         .align  16
619         .type   __condvar_cleanup2, @function
620 __condvar_cleanup2:
621         /* Stack frame:
622
623            rsp + 72
624                     +--------------------------+
625            rsp + 64 | %r12                     |
626                     +--------------------------+
627            rsp + 56 | %r13                     |
628                     +--------------------------+
629            rsp + 48 | %r14                     |
630                     +--------------------------+
631            rsp + 24 | unused                   |
632                     +--------------------------+
633            rsp + 16 | mutex pointer            |
634                     +--------------------------+
635            rsp +  8 | condvar pointer          |
636                     +--------------------------+
637            rsp +  4 | old broadcast_seq value  |
638                     +--------------------------+
639            rsp +  0 | old cancellation mode    |
640                     +--------------------------+
641         */
642
643         movq    %rax, 24(%rsp)
644
645         /* Get internal lock.  */
646         movq    8(%rsp), %rdi
647         movl    $1, %esi
648         xorl    %eax, %eax
649         LOCK
650 #if cond_lock == 0
651         cmpxchgl %esi, (%rdi)
652 #else
653         cmpxchgl %esi, cond_lock(%rdi)
654 #endif
655         jz      1f
656
657 #if cond_lock != 0
658         addq    $cond_lock, %rdi
659 #endif
660         cmpq    $-1, dep_mutex-cond_lock(%rdi)
661         movl    $LLL_PRIVATE, %eax
662         movl    $LLL_SHARED, %esi
663         cmovne  %eax, %esi
664         callq   __lll_lock_wait
665 #if cond_lock != 0
666         subq    $cond_lock, %rdi
667 #endif
668
669 1:      movl    broadcast_seq(%rdi), %edx
670         cmpl    4(%rsp), %edx
671         jne     3f
672
673         /* We increment the wakeup_seq counter only if it is lower than
674            total_seq.  If this is not the case the thread was woken and
675            then canceled.  In this case we ignore the signal.  */
676         movq    total_seq(%rdi), %rax
677         cmpq    wakeup_seq(%rdi), %rax
678         jbe     6f
679         incq    wakeup_seq(%rdi)
680         incl    cond_futex(%rdi)
681 6:      incq    woken_seq(%rdi)
682
683 3:      subl    $(1 << nwaiters_shift), cond_nwaiters(%rdi)
684
685         /* Wake up a thread which wants to destroy the condvar object.  */
686         xorq    %r12, %r12
687         cmpq    $0xffffffffffffffff, total_seq(%rdi)
688         jne     4f
689         movl    cond_nwaiters(%rdi), %eax
690         andl    $~((1 << nwaiters_shift) - 1), %eax
691         jne     4f
692
693         cmpq    $-1, dep_mutex(%rdi)
694         leaq    cond_nwaiters(%rdi), %rdi
695         movl    $1, %edx
696 #ifdef __ASSUME_PRIVATE_FUTEX
697         movl    $FUTEX_WAKE, %eax
698         movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
699         cmove   %eax, %esi
700 #else
701         movl    $0, %eax
702         movl    %fs:PRIVATE_FUTEX, %esi
703         cmove   %eax, %esi
704         orl     $FUTEX_WAKE, %esi
705 #endif
706         movl    $SYS_futex, %eax
707         syscall
708         subq    $cond_nwaiters, %rdi
709         movl    $1, %r12d
710
711 4:      LOCK
712 #if cond_lock == 0
713         decl    (%rdi)
714 #else
715         decl    cond_lock(%rdi)
716 #endif
717         je      2f
718 #if cond_lock != 0
719         addq    $cond_lock, %rdi
720 #endif
721         cmpq    $-1, dep_mutex-cond_lock(%rdi)
722         movl    $LLL_PRIVATE, %eax
723         movl    $LLL_SHARED, %esi
724         cmovne  %eax, %esi
725         callq   __lll_unlock_wake
726
727         /* Wake up all waiters to make sure no signal gets lost.  */
728 2:      testq   %r12, %r12
729         jnz     5f
730         addq    $cond_futex, %rdi
731         cmpq    $-1, dep_mutex-cond_futex(%rdi)
732         movl    $0x7fffffff, %edx
733 #ifdef __ASSUME_PRIVATE_FUTEX
734         movl    $FUTEX_WAKE, %eax
735         movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
736         cmove   %eax, %esi
737 #else
738         movl    $0, %eax
739         movl    %fs:PRIVATE_FUTEX, %esi
740         cmove   %eax, %esi
741         orl     $FUTEX_WAKE, %esi
742 #endif
743         movl    $SYS_futex, %eax
744         syscall
745
746 5:      movq    16(%rsp), %rdi
747         callq   __pthread_mutex_cond_lock
748
749         movq    24(%rsp), %rdi
750         movq    FRAME_SIZE(%rsp), %r15
751         movq    FRAME_SIZE+8(%rsp), %r14
752         movq    FRAME_SIZE+16(%rsp), %r13
753         movq    FRAME_SIZE+24(%rsp), %r12
754 .LcallUR:
755         call    _Unwind_Resume@PLT
756         hlt
757 .LENDCODE:
758         cfi_endproc
759         .size   __condvar_cleanup2, .-__condvar_cleanup2
760
761
762         .section .gcc_except_table,"a",@progbits
763 .LexceptSTART:
764         .byte   DW_EH_PE_omit                   # @LPStart format
765         .byte   DW_EH_PE_omit                   # @TType format
766         .byte   DW_EH_PE_uleb128                # call-site format
767         .uleb128 .Lcstend-.Lcstbegin
768 .Lcstbegin:
769         .uleb128 .LcleanupSTART1-.LSTARTCODE
770         .uleb128 .LcleanupEND1-.LcleanupSTART1
771         .uleb128 __condvar_cleanup2-.LSTARTCODE
772         .uleb128  0
773 #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
774         .uleb128 .LcleanupSTART2-.LSTARTCODE
775         .uleb128 .LcleanupEND2-.LcleanupSTART2
776         .uleb128 __condvar_cleanup2-.LSTARTCODE
777         .uleb128  0
778 #endif
779         .uleb128 .LcallUR-.LSTARTCODE
780         .uleb128 .LENDCODE-.LcallUR
781         .uleb128 0
782         .uleb128  0
783 .Lcstend:
784
785
786 #ifdef SHARED
787         .hidden DW.ref.__gcc_personality_v0
788         .weak   DW.ref.__gcc_personality_v0
789         .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
790         .align  8
791         .type   DW.ref.__gcc_personality_v0, @object
792         .size   DW.ref.__gcc_personality_v0, 8
793 DW.ref.__gcc_personality_v0:
794         .quad   __gcc_personality_v0
795 #endif