1 /* Copyright (C) 2003, 2004 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 <lowlevelcond.h>
21 #include "lowlevel-atomic.h"
29 /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
30 .globl __pthread_cond_wait
31 .type __pthread_cond_wait, @function
57 /* Get internal lock. */
61 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
63 CMPXCHG (r3, @r8, r4, r2)
71 .long _GLOBAL_OFFSET_TABLE_
75 /* Store the reference to the mutex. If there is already a
76 different value in there this is a bad user bug. */
77 mov.l @(dep_mutex,r8),r0
80 mov.l r9, @(dep_mutex,r8)
83 /* Unlock the mutex. */
99 mov.l @(total_seq,r8),r0
100 mov.l @(total_seq+4,r8),r1
103 mov.l r0,@(total_seq,r8)
104 mov.l r1,@(total_seq+4,r8)
105 mov.l @(cond_futex,r8),r0
107 mov.l r0,@(cond_futex,r8)
108 mov #(1 << clock_bits), r2
109 mov.l @(cond_nwaiters,r8), r0
111 mov.l r0, @(cond_nwaiters,r8)
113 /* Get and store current wakeup_seq value. */
114 mov.l @(wakeup_seq,r8), r10
115 mov.l @(wakeup_seq+4,r8), r11
116 mov.l @(broadcast_seq,r8), r0
120 mov.l @(cond_futex,r8),r0
125 DEC (@(cond_lock,r8), r2)
159 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
161 CMPXCHG (r3, @r8, r4, r2)
165 mov.l @(broadcast_seq,r8), r0
170 mov.l @(woken_seq,r8), r0
171 mov.l @(woken_seq+4,r8), r1
173 mov.l @(wakeup_seq,r8), r2
174 mov.l @(wakeup_seq+4,r8), r3
190 mov.l @(woken_seq,r8),r0
191 mov.l @(woken_seq+4,r8),r1
194 mov.l r0,@(woken_seq,r8)
195 mov.l r1,@(woken_seq+4,r8)
198 mov #(1 << clock_bits), r2
199 mov.l @(cond_nwaiters,r8),r0
201 mov.l r0,@(cond_nwaiters,r8)
203 /* Wake up a thread which wants to destroy the condvar object. */
204 mov.l @(total_seq,r8),r0
205 mov.l @(total_seq+4,r8),r1
210 mov #((1 << clock_bits) - 1), r1
212 mov.l @(cond_nwaiters,r8),r0
217 add #cond_nwaiters, r4
228 DEC (@(cond_lock,r8), r2)
240 /* We return the result of the mutex_lock operation. */
254 .long __pthread_mutex_unlock_usercnt-.Lmunlock0b
256 .long __pthread_enable_asynccancel-.Lenable0b
258 .long __pthread_disable_asynccancel-.Ldisable0b
260 .long __pthread_mutex_cond_lock-.Lmlocki0b
263 /* Initial locking failed. */
275 /* Unlock in loop requires waekup. */
288 /* Locking in loop failed. */
301 /* Unlock after loop requires wakeup. */
314 /* The initial unlocking of the mutex failed. */
317 DEC (@(cond_lock,r8), r2)
339 .long __lll_mutex_lock_wait-.Lmwait0b
341 .long __lll_mutex_unlock_wake-.Lmwake0b
343 .long __lll_mutex_lock_wait-.Lmwait1b
345 .long __lll_mutex_unlock_wake-.Lmwake1b
347 .long __lll_mutex_unlock_wake-.Lmwake2b
348 .size __pthread_cond_wait, .-__pthread_cond_wait
349 weak_alias (__pthread_cond_wait, pthread_cond_wait)
352 .type __condvar_w_cleanup, @function
356 /* Get internal lock. */
360 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
362 CMPXCHG (r3, @r8, r4, r2)
377 mov.l @(broadcast_seq,r8), r0
386 mov.l @(wakeup_seq,r8),r0
387 mov.l @(wakeup_seq+4,r8),r1
390 mov.l r0,@(wakeup_seq,r8)
391 mov.l r1,@(wakeup_seq+4,r8)
392 mov.l @(cond_futex,r8),r0
394 mov.l r0,@(cond_futex,r8)
397 mov.l @(woken_seq,r8),r0
398 mov.l @(woken_seq+4,r8),r1
401 mov.l r0,@(woken_seq,r8)
402 mov.l r1,@(woken_seq+4,r8)
405 mov #(1 << clock_bits), r2
406 mov.l @(cond_nwaiters,r8),r0
408 mov.l r0,@(cond_nwaiters,r8)
410 /* Wake up a thread which wants to destroy the condvar object. */
412 mov.l @(total_seq,r8),r0
413 mov.l @(total_seq+4,r8),r1
418 mov #((1 << clock_bits) - 1), r1
420 mov.l @(cond_nwaiters,r8),r0
425 add #cond_nwaiters, r4
437 DEC (@(cond_lock,r8), r2)
454 /* Wake up all waiters to make sure no signal gets lost. */
461 shlr r6 /* r6 = 0x7fffffff */
485 .long __lll_mutex_lock_wait-.Lmwait3b
487 .long __lll_mutex_unlock_wake-.Lmwake3b
489 .long __pthread_mutex_cond_lock-.Lmlocki3b
492 .long _Unwind_Resume@GOTOFF
497 .size __condvar_w_cleanup, .-__condvar_w_cleanup
500 .section .gcc_except_table,"a",@progbits
502 .byte 0xff ! @LPStart format (omit)
503 .byte 0xff ! @TType format (omit)
504 .byte 0x0b ! call-site format
506 .uleb128 .Lcstend-.Lcstbegin
508 .ualong .LcleanupSTART-.LSTARTCODE
509 .ualong .LcleanupEND-.LcleanupSTART
510 .ualong __condvar_w_cleanup-.LSTARTCODE
512 .ualong .LcallUR-.LSTARTCODE
513 .ualong .LENDCODE-.LcallUR
518 .section .eh_frame,"a",@progbits
520 .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
523 .byte 1 ! Version number.
525 .string "zPLR" ! NUL-terminated augmentation
528 .string "zPL" ! NUL-terminated augmentation
531 .uleb128 1 ! Code alignment factor.
532 .sleb128 -4 ! Data alignment factor.
533 .byte 0x11 ! Return address register
536 .uleb128 7 ! Augmentation value length.
537 .byte 0x9b ! Personality: DW_EH_PE_pcrel
539 ! + DW_EH_PE_indirect
540 .ualong DW.ref.__gcc_personality_v0-.
541 .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
543 .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
546 .uleb128 6 ! Augmentation value length.
547 .byte 0x0 ! Personality: absolute
548 .ualong __gcc_personality_v0
549 .byte 0x0 ! LSDA Encoding: absolute
551 .byte 0x0c ! DW_CFA_def_cfa
557 .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
559 .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
561 .ualong .LSTARTCODE-. ! PC-relative start address
564 .ualong .LSTARTCODE ! Start address of the code.
566 .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
567 .uleb128 4 ! Augmentation size
569 .ualong .LexceptSTART-.
571 .ualong .LexceptSTART
574 .ualong .Lpush_r8-.LSTARTCODE
580 .ualong .Lpush_r9-.Lpush_r8
586 .ualong .Lpush_r10-.Lpush_r9
592 .ualong .Lpush_r11-.Lpush_r10
598 .ualong .Lpush_r12-.Lpush_r11
604 .ualong .Lpush_pr-.Lpush_r12
610 .ualong .Lalloc-.Lpush_pr
617 .hidden DW.ref.__gcc_personality_v0
618 .weak DW.ref.__gcc_personality_v0
619 .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
621 .type DW.ref.__gcc_personality_v0, @object
622 .size DW.ref.__gcc_personality_v0, 4
623 DW.ref.__gcc_personality_v0:
624 .long __gcc_personality_v0