1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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.
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.
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
21 #include <shlib-compat.h>
22 #include <lowlevelcond.h>
23 #include <tcb-offsets.h>
38 /* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
39 .globl __pthread_cond_wait
40 .type __pthread_cond_wait, @function
55 /* Get internal lock. */
62 cmpxchgl %edx, cond_lock(%ebx)
66 /* Store the reference to the mutex. If there is already a
67 different value in there this is a bad user bug. */
68 2: cmpl $-1, dep_mutex(%ebx)
71 movl %eax, dep_mutex(%ebx)
73 /* Unlock the mutex. */
75 call __pthread_mutex_unlock_usercnt
80 addl $1, total_seq(%ebx)
81 adcl $0, total_seq+4(%ebx)
84 subl $FRAME_SIZE, %esp
87 /* Get and store current wakeup_seq value. */
88 movl wakeup_seq(%ebx), %edi
89 movl wakeup_seq+4(%ebx), %edx
90 movl broadcast_seq(%ebx), %eax
100 subl $1, cond_lock(%ebx)
105 4: call __pthread_enable_asynccancel
108 movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */
110 addl $wakeup_seq, %ebx
112 movl $SYS_futex, %eax
114 subl $wakeup_seq, %ebx
118 call __pthread_disable_asynccancel
126 cmpxchgl %edx, (%ebx)
128 cmpxchgl %edx, cond_lock(%ebx)
132 6: movl broadcast_seq(%ebx), %eax
136 movl woken_seq(%ebx), %eax
137 movl woken_seq+4(%ebx), %ecx
139 movl wakeup_seq(%ebx), %edi
140 movl wakeup_seq+4(%ebx), %edx
152 9: addl $1, woken_seq(%ebx)
153 adcl $0, woken_seq+4(%ebx)
160 subl $1, cond_lock(%ebx)
164 11: movl 20+FRAME_SIZE(%esp), %eax
165 call __pthread_mutex_cond_lock
166 addl $FRAME_SIZE, %esp
176 /* We return the result of the mutex_lock operation. */
179 /* Initial locking failed. */
185 leal cond_lock(%ebx), %ecx
187 call __lll_mutex_lock_wait
190 /* Unlock in loop requires waekup. */
196 leal cond_lock(%ebx), %eax
198 call __lll_mutex_unlock_wake
201 /* Locking in loop failed. */
206 leal cond_lock(%ebx), %ecx
208 call __lll_mutex_lock_wait
211 /* Unlock after loop requires wakeup. */
216 leal cond_lock(%ebx), %eax
218 call __lll_mutex_unlock_wake
221 /* The initial unlocking of the mutex failed. */
228 subl $1, cond_lock(%ebx)
236 leal cond_lock(%ebx), %eax
238 call __lll_mutex_unlock_wake
242 .size __pthread_cond_wait, .-__pthread_cond_wait
243 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
247 .type __condvar_w_cleanup2, @function
248 __condvar_w_cleanup2:
249 subl $wakeup_seq, %ebx
250 .size __condvar_w_cleanup2, .-__condvar_w_cleanup2
252 .type __condvar_w_cleanup, @function
256 /* Get internal lock. */
261 cmpxchgl %edx, (%ebx)
263 cmpxchgl %edx, cond_lock(%ebx)
270 leal cond_lock(%ebx), %ecx
272 call __lll_mutex_lock_wait
274 1: movl broadcast_seq(%ebx), %eax
278 addl $1, wakeup_seq(%ebx)
279 adcl $0, wakeup_seq+4(%ebx)
281 addl $1, woken_seq(%ebx)
282 adcl $0, woken_seq+4(%ebx)
288 subl $1, cond_lock(%ebx)
295 leal cond_lock(%ebx), %eax
297 call __lll_mutex_unlock_wake
299 /* Wake up all waiters to make sure no signal gets lost. */
300 2: addl $wakeup_seq, %ebx
301 movl $FUTEX_WAKE, %ecx
302 movl $SYS_futex, %eax
303 movl $0x7fffffff, %edx
306 movl 20+FRAME_SIZE(%esp), %eax
307 call __pthread_mutex_cond_lock
314 .size __condvar_w_cleanup, .-__condvar_w_cleanup
317 .section .gcc_except_table,"a",@progbits
319 .byte 0xff # @LPStart format (omit)
320 .byte 0xff # @TType format (omit)
321 .byte 0x0b # call-site format
323 .uleb128 .Lcstend-.Lcstbegin
325 .long .LcleanupSTART-.LSTARTCODE
326 .long .Ladd_wakeup-.LcleanupSTART
327 .long __condvar_w_cleanup-.LSTARTCODE
329 .long .Ladd_wakeup-.LSTARTCODE
330 .long .Lsub_wakeup-.Ladd_wakeup
331 .long __condvar_w_cleanup2-.LSTARTCODE
333 .long .Lsub_wakeup-.LSTARTCODE
334 .long .LcleanupEND-.Lsub_wakeup
335 .long __condvar_w_cleanup-.LSTARTCODE
337 .long .LcallUR-.LSTARTCODE
338 .long .LENDCODE-.LcallUR
343 .section .eh_frame,"a",@progbits
345 .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
348 .byte 1 # Version number.
350 .string "zPLR" # NUL-terminated augmentation
353 .string "zPL" # NUL-terminated augmentation
356 .uleb128 1 # Code alignment factor.
357 .sleb128 -4 # Data alignment factor.
358 .byte 8 # Return address register
361 .uleb128 7 # Augmentation value length.
362 .byte 0x9b # Personality: DW_EH_PE_pcrel
364 # + DW_EH_PE_indirect
365 .long DW.ref.__gcc_personality_v0-.
366 .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
368 .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
371 .uleb128 6 # Augmentation value length.
372 .byte 0x0 # Personality: absolute
373 .long __gcc_personality_v0
374 .byte 0x0 # LSDA Encoding: absolute
376 .byte 0x0c # DW_CFA_def_cfa
379 .byte 0x88 # DW_CFA_offset, column 0x8
384 .long .LENDFDE-.LSTARTFDE # Length of the FDE.
386 .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
388 .long .LSTARTCODE-. # PC-relative start address
391 .long .LSTARTCODE # Start address of the code.
393 .long .LENDCODE-.LSTARTCODE # Length of the code.
394 .uleb128 4 # Augmentation size
396 .long .LexceptSTART-.
400 .byte 0x40+.Lpush_edi-.LSTARTCODE # DW_CFA_advance_loc+N
401 .byte 14 # DW_CFA_def_cfa_offset
403 .byte 0x87 # DW_CFA_offset %edi
405 .byte 0x40+.Lpush_esi-.Lpush_edi # DW_CFA_advance_loc+N
406 .byte 14 # DW_CFA_def_cfa_offset
408 .byte 0x86 # DW_CFA_offset %esi
410 .byte 0x40+.Lpush_ebx-.Lpush_esi # DW_CFA_advance_loc+N
411 .byte 14 # DW_CFA_def_cfa_offset
413 .byte 0x83 # DW_CFA_offset %ebx
415 .byte 2 # DW_CFA_advance_loc1
416 .byte .Lsubl-.Lpush_ebx
417 .byte 14 # DW_CFA_def_cfa_offset
418 .uleb128 16+FRAME_SIZE
419 .byte 2 # DW_CFA_advance_loc1
421 .byte 14 # DW_CFA_def_cfa_offset
423 .byte 0x40+ .Lpop_ebx-.Laddl # DW_CFA_advance_loc+N
424 .byte 14 # DW_CFA_def_cfa_offset
426 .byte 0xc3 # DW_CFA_restore %ebx
427 .byte 0x40+.Lpop_esi-.Lpop_ebx # DW_CFA_advance_loc+N
428 .byte 14 # DW_CFA_def_cfa_offset
430 .byte 0xc6 # DW_CFA_restore %esi
431 .byte 0x40+.Lpop_edi-.Lpop_esi # DW_CFA_advance_loc+N
432 .byte 14 # DW_CFA_def_cfa_offset
434 .byte 0xc7 # DW_CFA_restore %edi
435 .byte 0x40+.LSbl1-.Lpop_edi # DW_CFA_advance_loc+N
436 .byte 14 # DW_CFA_def_cfa_offset
438 .byte 0x87 # DW_CFA_offset %edi
440 .byte 0x86 # DW_CFA_offset %esi
442 .byte 0x83 # DW_CFA_offset %ebx
444 .byte 0x40+.LSbl2-.LSbl1 # DW_CFA_advance_loc+N
445 .byte 14 # DW_CFA_def_cfa_offset
446 .uleb128 16+FRAME_SIZE
447 .byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N
448 .byte 14 # DW_CFA_def_cfa_offset
450 .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N
451 .byte 14 # DW_CFA_def_cfa_offset
452 .uleb128 16+FRAME_SIZE
458 .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
459 .globl __i686.get_pc_thunk.cx
460 .hidden __i686.get_pc_thunk.cx
461 .type __i686.get_pc_thunk.cx,@function
462 __i686.get_pc_thunk.cx:
465 .size __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
469 .hidden DW.ref.__gcc_personality_v0
470 .weak DW.ref.__gcc_personality_v0
471 .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
473 .type DW.ref.__gcc_personality_v0, @object
474 .size DW.ref.__gcc_personality_v0, 4
475 DW.ref.__gcc_personality_v0:
476 .long __gcc_personality_v0