1 /* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 #include <shlib-compat.h>
21 #include <lowlevelcond.h>
22 #include "lowlevel-atomic.h"
31 /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
32 .globl __pthread_cond_wait
33 .type __pthread_cond_wait, @function
59 /* Get internal lock. */
63 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
65 CMPXCHG (r3, @r8, r4, r2)
73 .long _GLOBAL_OFFSET_TABLE_
77 /* Store the reference to the mutex. If there is already a
78 different value in there this is a bad user bug. */
79 mov.l @(dep_mutex,r8),r0
82 mov.l r9, @(dep_mutex,r8)
85 /* Unlock the mutex. */
101 mov.l @(total_seq,r8),r0
102 mov.l @(total_seq+4,r8),r1
105 mov.l r0,@(total_seq,r8)
106 mov.l r1,@(total_seq+4,r8)
107 mov.l @(cond_futex,r8),r0
109 mov.l r0,@(cond_futex,r8)
110 mov #(1 << nwaiters_shift), r2
111 mov.l @(cond_nwaiters,r8), r0
113 mov.l r0, @(cond_nwaiters,r8)
115 /* Get and store current wakeup_seq value. */
116 mov.l @(wakeup_seq,r8), r10
117 mov.l @(wakeup_seq+4,r8), r11
118 mov.l @(broadcast_seq,r8), r0
122 mov.l @(cond_futex,r8),r0
127 DEC (@(cond_lock,r8), r2)
161 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
163 CMPXCHG (r3, @r8, r4, r2)
167 mov.l @(broadcast_seq,r8), r0
172 mov.l @(woken_seq,r8), r0
173 mov.l @(woken_seq+4,r8), r1
175 mov.l @(wakeup_seq,r8), r2
176 mov.l @(wakeup_seq+4,r8), r3
192 mov.l @(woken_seq,r8),r0
193 mov.l @(woken_seq+4,r8),r1
196 mov.l r0,@(woken_seq,r8)
197 mov.l r1,@(woken_seq+4,r8)
200 mov #(1 << nwaiters_shift), r2
201 mov.l @(cond_nwaiters,r8),r0
203 mov.l r0,@(cond_nwaiters,r8)
205 /* Wake up a thread which wants to destroy the condvar object. */
206 mov.l @(total_seq,r8),r0
207 mov.l @(total_seq+4,r8),r1
212 mov #((1 << nwaiters_shift) - 1), r1
214 mov.l @(cond_nwaiters,r8),r0
219 add #cond_nwaiters, r4
230 DEC (@(cond_lock,r8), r2)
242 /* We return the result of the mutex_lock operation. */
256 .long __pthread_mutex_unlock_usercnt-.Lmunlock0b
258 .long __pthread_enable_asynccancel-.Lenable0b
260 .long __pthread_disable_asynccancel-.Ldisable0b
262 .long __pthread_mutex_cond_lock-.Lmlocki0b
265 /* Initial locking failed. */
277 /* Unlock in loop requires waekup. */
290 /* Locking in loop failed. */
303 /* Unlock after loop requires wakeup. */
316 /* The initial unlocking of the mutex failed. */
319 DEC (@(cond_lock,r8), r2)
341 .long __lll_mutex_lock_wait-.Lmwait0b
343 .long __lll_mutex_unlock_wake-.Lmwake0b
345 .long __lll_mutex_lock_wait-.Lmwait1b
347 .long __lll_mutex_unlock_wake-.Lmwake1b
349 .long __lll_mutex_unlock_wake-.Lmwake2b
350 .size __pthread_cond_wait, .-__pthread_cond_wait
351 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
355 .type __condvar_w_cleanup, @function
359 /* Get internal lock. */
363 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
365 CMPXCHG (r3, @r8, r4, r2)
380 mov.l @(broadcast_seq,r8), r0
388 /* We increment the wakeup_seq counter only if it is lower than
389 total_seq. If this is not the case the thread was woken and
390 then canceled. In this case we ignore the signal. */
391 mov.l @(total_seq+4,r8), r0
392 mov.l @(wakeup_seq+4,r8), r1
397 mov.l @(total_seq,r8), r0
398 mov.l @(wakeup_seq,r8), r1
404 mov.l @(wakeup_seq,r8),r0
405 mov.l @(wakeup_seq+4,r8),r1
408 mov.l r0,@(wakeup_seq,r8)
409 mov.l r1,@(wakeup_seq+4,r8)
410 mov.l @(cond_futex,r8),r0
412 mov.l r0,@(cond_futex,r8)
416 mov.l @(woken_seq,r8),r0
417 mov.l @(woken_seq+4,r8),r1
420 mov.l r0,@(woken_seq,r8)
421 mov.l r1,@(woken_seq+4,r8)
424 mov #(1 << nwaiters_shift), r2
425 mov.l @(cond_nwaiters,r8),r0
427 mov.l r0,@(cond_nwaiters,r8)
429 /* Wake up a thread which wants to destroy the condvar object. */
431 mov.l @(total_seq,r8),r0
432 mov.l @(total_seq+4,r8),r1
437 mov #((1 << nwaiters_shift) - 1), r1
439 mov.l @(cond_nwaiters,r8),r0
444 add #cond_nwaiters, r4
456 DEC (@(cond_lock,r8), r2)
473 /* Wake up all waiters to make sure no signal gets lost. */
480 shlr r6 /* r6 = 0x7fffffff */
504 .long __lll_mutex_lock_wait-.Lmwait3b
506 .long __lll_mutex_unlock_wake-.Lmwake3b
508 .long __pthread_mutex_cond_lock-.Lmlocki3b
511 .long _Unwind_Resume@GOTOFF
516 .size __condvar_w_cleanup, .-__condvar_w_cleanup
519 .section .gcc_except_table,"a",@progbits
521 .byte 0xff ! @LPStart format (omit)
522 .byte 0xff ! @TType format (omit)
523 .byte 0x0b ! call-site format
525 .uleb128 .Lcstend-.Lcstbegin
527 .ualong .LcleanupSTART-.LSTARTCODE
528 .ualong .LcleanupEND-.LcleanupSTART
529 .ualong __condvar_w_cleanup-.LSTARTCODE
531 .ualong .LcallUR-.LSTARTCODE
532 .ualong .LENDCODE-.LcallUR
537 .section .eh_frame,"a",@progbits
539 .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
542 .byte 1 ! Version number.
544 .string "zPLR" ! NUL-terminated augmentation
547 .string "zPL" ! NUL-terminated augmentation
550 .uleb128 1 ! Code alignment factor.
551 .sleb128 -4 ! Data alignment factor.
552 .byte 0x11 ! Return address register
555 .uleb128 7 ! Augmentation value length.
556 .byte 0x9b ! Personality: DW_EH_PE_pcrel
558 ! + DW_EH_PE_indirect
559 .ualong DW.ref.__gcc_personality_v0-.
560 .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
562 .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
565 .uleb128 6 ! Augmentation value length.
566 .byte 0x0 ! Personality: absolute
567 .ualong __gcc_personality_v0
568 .byte 0x0 ! LSDA Encoding: absolute
570 .byte 0x0c ! DW_CFA_def_cfa
576 .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
578 .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
580 .ualong .LSTARTCODE-. ! PC-relative start address
583 .ualong .LSTARTCODE ! Start address of the code.
585 .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
586 .uleb128 4 ! Augmentation size
588 .ualong .LexceptSTART-.
590 .ualong .LexceptSTART
593 .ualong .Lpush_r8-.LSTARTCODE
599 .ualong .Lpush_r9-.Lpush_r8
605 .ualong .Lpush_r10-.Lpush_r9
611 .ualong .Lpush_r11-.Lpush_r10
617 .ualong .Lpush_r12-.Lpush_r11
623 .ualong .Lpush_pr-.Lpush_r12
629 .ualong .Lalloc-.Lpush_pr
636 .hidden DW.ref.__gcc_personality_v0
637 .weak DW.ref.__gcc_personality_v0
638 .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
640 .type DW.ref.__gcc_personality_v0, @object
641 .size DW.ref.__gcc_personality_v0, 4
642 DW.ref.__gcc_personality_v0:
643 .long __gcc_personality_v0