]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
2.5-18.1
[thirdparty/glibc.git] / nptl / sysdeps / unix / sysv / linux / sh / pthread_cond_wait.S
CommitLineData
0ecb606c 1/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
a54e8d33
UD
2 This file is part of the GNU C Library.
3
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.
8
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.
13
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
17 02111-1307 USA. */
18
19#include <sysdep.h>
20#include <shlib-compat.h>
21#include <lowlevelcond.h>
22#include "lowlevel-atomic.h"
23
24#define SYS_futex 240
25#define FUTEX_WAIT 0
26#define FUTEX_WAKE 1
27
28
29 .text
30
a54e8d33
UD
31/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
32 .globl __pthread_cond_wait
33 .type __pthread_cond_wait, @function
34 .align 5
35__pthread_cond_wait:
07bd2a3f 36.LSTARTCODE:
a54e8d33 37 mov.l r8, @-r15
07bd2a3f 38.Lpush_r8:
4a17085f 39 mov.l r9, @-r15
07bd2a3f 40.Lpush_r9:
4a17085f 41 mov.l r10, @-r15
07bd2a3f 42.Lpush_r10:
4a17085f 43 mov.l r11, @-r15
07bd2a3f 44.Lpush_r11:
4a17085f 45 mov.l r12, @-r15
07bd2a3f 46.Lpush_r12:
a54e8d33 47 sts.l pr, @-r15
07bd2a3f 48.Lpush_pr:
dd731d53 49 add #-48, r15
07bd2a3f 50.Lalloc:
a54e8d33
UD
51 mov r4, r8
52 mov r5, r9
07bd2a3f
UD
53#ifdef PIC
54 mova .Lgot0, r0
55 mov.l .Lgot0, r12
56 add r0, r12
57#endif
a54e8d33
UD
58
59 /* Get internal lock. */
fa3cbe3d
UD
60 mov #0, r3
61 mov #1, r4
a54e8d33 62#if cond_lock != 0
fa3cbe3d 63 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
a54e8d33 64#else
fa3cbe3d 65 CMPXCHG (r3, @r8, r4, r2)
a54e8d33 66#endif
4a17085f
UD
67 bt 2f
68 bra 1f
69 nop
07bd2a3f
UD
70#ifdef PIC
71 .align 2
72.Lgot0:
73 .long _GLOBAL_OFFSET_TABLE_
74#endif
ea2630c6 75
4a17085f 762:
ea2630c6
UD
77 /* Store the reference to the mutex. If there is already a
78 different value in there this is a bad user bug. */
07bd2a3f
UD
79 mov.l @(dep_mutex,r8),r0
80 cmp/eq #-1, r0
81 bt 15f
ea2630c6
UD
82 mov.l r9, @(dep_mutex,r8)
83
07bd2a3f 8415:
a54e8d33
UD
85 /* Unlock the mutex. */
86 mov.l .Lmunlock0, r1
4a17085f 87 mov #0, r5
a54e8d33
UD
88 bsrf r1
89 mov r9, r4
90.Lmunlock0b:
91
dd731d53 92 tst r0, r0
4a17085f
UD
93 bt 0f
94 bra 12f
95 nop
960:
a54e8d33
UD
97 mov #1, r2
98 mov #0, r3
99
100 clrt
101 mov.l @(total_seq,r8),r0
102 mov.l @(total_seq+4,r8),r1
103 addc r2, r0
104 addc r3, r1
105 mov.l r0,@(total_seq,r8)
106 mov.l r1,@(total_seq+4,r8)
7c370086
UD
107 mov.l @(cond_futex,r8),r0
108 add r2, r0
109 mov.l r0,@(cond_futex,r8)
9b2dc515
UD
110 mov #(1 << clock_bits), r2
111 mov.l @(cond_nwaiters,r8), r0
112 add r2, r0
113 mov.l r0, @(cond_nwaiters,r8)
a54e8d33 114
a54e8d33 115 /* Get and store current wakeup_seq value. */
4a17085f
UD
116 mov.l @(wakeup_seq,r8), r10
117 mov.l @(wakeup_seq+4,r8), r11
fbf86dda
UD
118 mov.l @(broadcast_seq,r8), r0
119 mov.l r0, @(4,r15)
a54e8d33
UD
120
1218:
7c370086
UD
122 mov.l @(cond_futex,r8),r0
123 mov.l r0, @(8,r15)
124
a54e8d33
UD
125 /* Unlock. */
126#if cond_lock != 0
127 DEC (@(cond_lock,r8), r2)
128#else
129 DEC (@r8, r2)
130#endif
131 tst r2, r2
132 bf 3f
1334:
07bd2a3f 134.LcleanupSTART:
a54e8d33
UD
135 mov.l .Lenable0, r1
136 bsrf r1
ea2630c6 137 nop
a54e8d33 138.Lenable0b:
4a17085f 139 mov.l r0, @r15
a54e8d33
UD
140
141 mov #0, r7
142 mov #FUTEX_WAIT, r5
7c370086 143 mov.l @(8,r15), r6
a54e8d33 144 mov r8, r4
7c370086 145 add #cond_futex, r4
a54e8d33
UD
146 mov #SYS_futex, r3
147 extu.b r3, r3
148 trapa #0x14
149 SYSCALL_INST_PAD
150
151 mov.l .Ldisable0, r1
152 bsrf r1
4a17085f 153 mov.l @r15, r4
a54e8d33 154.Ldisable0b:
07bd2a3f 155.LcleanupEND:
a54e8d33
UD
156
157 /* Lock. */
fa3cbe3d
UD
158 mov #0, r3
159 mov #1, r4
a54e8d33 160#if cond_lock != 0
fa3cbe3d 161 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
a54e8d33 162#else
fa3cbe3d 163 CMPXCHG (r3, @r8, r4, r2)
a54e8d33 164#endif
a54e8d33
UD
165 bf 5f
1666:
fbf86dda
UD
167 mov.l @(broadcast_seq,r8), r0
168 mov.l @(4,r15), r1
169 cmp/eq r0, r1
170 bf 16f
171
a54e8d33
UD
172 mov.l @(woken_seq,r8), r0
173 mov.l @(woken_seq+4,r8), r1
174
175 mov.l @(wakeup_seq,r8), r2
176 mov.l @(wakeup_seq+4,r8), r3
177
07bd2a3f
UD
178 cmp/eq r3, r11
179 bf 7f
180 cmp/eq r2, r10
a54e8d33
UD
181 bt 8b
1827:
07bd2a3f
UD
183 cmp/eq r1, r3
184 bf 9f
185 cmp/eq r0, r2
a54e8d33 186 bt 8b
a54e8d33
UD
1879:
188 mov #1, r2
189 mov #0, r3
190
191 clrt
192 mov.l @(woken_seq,r8),r0
193 mov.l @(woken_seq+4,r8),r1
194 addc r2, r0
195 addc r3, r1
196 mov.l r0,@(woken_seq,r8)
197 mov.l r1,@(woken_seq+4,r8)
198
9b2dc515
UD
19916:
200 mov #(1 << clock_bits), r2
201 mov.l @(cond_nwaiters,r8),r0
202 sub r2, r0
203 mov.l r0,@(cond_nwaiters,r8)
204
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
208 and r1, r0
209 not r0, r0
210 cmp/eq #0, r0
211 bf/s 17f
212 mov #((1 << clock_bits) - 1), r1
213 not r1, r1
214 mov.l @(cond_nwaiters,r8),r0
215 tst r1, r0
216 bf 17f
217
218 mov r8, r4
219 add #cond_nwaiters, r4
220 mov #FUTEX_WAKE, r5
221 mov #1, r6
222 mov #0, r7
223 mov #SYS_futex, r3
224 extu.b r3, r3
225 trapa #0x14
226 SYSCALL_INST_PAD
227
22817:
a54e8d33
UD
229#if cond_lock != 0
230 DEC (@(cond_lock,r8), r2)
231#else
232 DEC (@r8, r2)
233#endif
234 tst r2, r2
235 bf 10f
236
23711:
a54e8d33
UD
238 mov.l .Lmlocki0, r1
239 bsrf r1
07bd2a3f 240 mov r9, r4
a54e8d33 241.Lmlocki0b:
a54e8d33 242 /* We return the result of the mutex_lock operation. */
dd731d53
UD
243
24414:
245 add #48, r15
a54e8d33 246 lds.l @r15+, pr
4a17085f
UD
247 mov.l @r15+, r12
248 mov.l @r15+, r11
249 mov.l @r15+, r10
a54e8d33
UD
250 mov.l @r15+, r9
251 rts
4a17085f 252 mov.l @r15+, r8
a54e8d33
UD
253
254 .align 2
255.Lmunlock0:
4a17085f 256 .long __pthread_mutex_unlock_usercnt-.Lmunlock0b
a54e8d33 257.Lenable0:
ea2630c6 258 .long __pthread_enable_asynccancel-.Lenable0b
a54e8d33
UD
259.Ldisable0:
260 .long __pthread_disable_asynccancel-.Ldisable0b
a54e8d33 261.Lmlocki0:
ea2630c6 262 .long __pthread_mutex_cond_lock-.Lmlocki0b
a54e8d33
UD
263
2641:
265 /* Initial locking failed. */
266 mov r8, r5
267#if cond_lock != 0
268 add #cond_lock, r5
269#endif
270 mov.l .Lmwait0, r1
271 bsrf r1
272 mov r2, r4
273.Lmwait0b:
274 bra 2b
275 nop
2763:
277 /* Unlock in loop requires waekup. */
278 mov r8, r4
279#if cond_lock != 0
280 add #cond_lock, r4
281#endif
282 mov.l .Lmwake0, r1
283 bsrf r1
284 nop
285.Lmwake0b:
286 bra 4b
287 nop
288
2895:
290 /* Locking in loop failed. */
291 mov r8, r5
292#if cond_lock != 0
293 add #cond_lock, r5
294#endif
295 mov.l .Lmwait1, r1
296 bsrf r1
297 mov r2, r4
298.Lmwait1b:
299 bra 6b
300 nop
301
30210:
303 /* Unlock after loop requires wakeup. */
304 mov r8, r4
305#if cond_lock != 0
306 add #cond_lock, r4
307#endif
308 mov.l .Lmwake1, r1
309 bsrf r1
310 nop
311.Lmwake1b:
312 bra 11b
313 nop
314
dd731d53
UD
31512:
316 /* The initial unlocking of the mutex failed. */
4a17085f 317 mov.l r0, @(12,r15)
dd731d53
UD
318#if cond_lock != 0
319 DEC (@(cond_lock,r8), r2)
320#else
321 DEC (@r8, r2)
322#endif
323 tst r2, r2
324 bf 13f
325
326 mov r8, r4
327#if cond_lock != 0
328 add #cond_lock, r4
329#endif
330 mov.l .Lmwake2, r1
331 bsrf r1
332 nop
333.Lmwake2b:
334
33513:
336 bra 14b
4a17085f 337 mov.l @(12,r15), r0
dd731d53 338
a54e8d33
UD
339 .align 2
340.Lmwait0:
341 .long __lll_mutex_lock_wait-.Lmwait0b
342.Lmwake0:
343 .long __lll_mutex_unlock_wake-.Lmwake0b
344.Lmwait1:
345 .long __lll_mutex_lock_wait-.Lmwait1b
346.Lmwake1:
347 .long __lll_mutex_unlock_wake-.Lmwake1b
dd731d53
UD
348.Lmwake2:
349 .long __lll_mutex_unlock_wake-.Lmwake2b
a54e8d33
UD
350 .size __pthread_cond_wait, .-__pthread_cond_wait
351versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
352 GLIBC_2_3_2)
07bd2a3f
UD
353
354
355 .type __condvar_w_cleanup, @function
356__condvar_w_cleanup:
357 mov r4, r11
358
359 /* Get internal lock. */
360 mov #0, r3
361 mov #1, r4
362#if cond_lock != 0
363 CMPXCHG (r3, @(cond_lock,r8), r4, r2)
364#else
365 CMPXCHG (r3, @r8, r4, r2)
366#endif
367 bt 1f
368 nop
369
370 mov r8, r5
371#if cond_lock != 0
372 add #cond_lock, r5
373#endif
374 mov.l .Lmwait3, r1
375 bsrf r1
376 mov r2, r4
377.Lmwait3b:
378
3791:
fbf86dda
UD
380 mov.l @(broadcast_seq,r8), r0
381 mov.l @(4,r15), r1
382 cmp/eq r0, r1
383 bf 3f
384
07bd2a3f
UD
385 mov #1, r2
386 mov #0, r3
387
0ecb606c
JJ
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
393 cmp/hi r1, r0
394 bt/s 6f
395 cmp/hi r0, r1
396 bt 7f
397 mov.l @(total_seq,r8), r0
398 mov.l @(wakeup_seq,r8), r1
399 cmp/hs r0, r1
400 bt 7f
401
4026:
07bd2a3f
UD
403 clrt
404 mov.l @(wakeup_seq,r8),r0
405 mov.l @(wakeup_seq+4,r8),r1
406 addc r2, r0
407 addc r3, r1
408 mov.l r0,@(wakeup_seq,r8)
409 mov.l r1,@(wakeup_seq+4,r8)
7c370086
UD
410 mov.l @(cond_futex,r8),r0
411 add r2, r0
412 mov.l r0,@(cond_futex,r8)
07bd2a3f 413
0ecb606c 4147:
fbf86dda
UD
415 clrt
416 mov.l @(woken_seq,r8),r0
417 mov.l @(woken_seq+4,r8),r1
418 addc r2, r0
419 addc r3, r1
420 mov.l r0,@(woken_seq,r8)
421 mov.l r1,@(woken_seq+4,r8)
422
9b2dc515
UD
4233:
424 mov #(1 << clock_bits), r2
425 mov.l @(cond_nwaiters,r8),r0
426 sub r2, r0
427 mov.l r0,@(cond_nwaiters,r8)
428
429 /* Wake up a thread which wants to destroy the condvar object. */
430 mov #0, r10
431 mov.l @(total_seq,r8),r0
432 mov.l @(total_seq+4,r8),r1
433 and r1, r0
434 not r0, r0
435 cmp/eq #0, r0
436 bf/s 4f
437 mov #((1 << clock_bits) - 1), r1
438 not r1, r1
439 mov.l @(cond_nwaiters,r8),r0
440 tst r1, r0
441 bf 4f
442
443 mov r8, r4
444 add #cond_nwaiters, r4
445 mov #FUTEX_WAKE, r5
446 mov #1, r6
447 mov #0, r7
448 mov #SYS_futex, r3
449 extu.b r3, r3
450 trapa #0x14
451 SYSCALL_INST_PAD
452 mov #1, r10
453
4544:
07bd2a3f
UD
455#if cond_lock != 0
456 DEC (@(cond_lock,r8), r2)
457#else
458 DEC (@r8, r2)
459#endif
460 tst r2, r2
461 bt 2f
462
463 mov r8, r4
464#if cond_lock != 0
465 add #cond_lock, r4
466#endif
467 mov.l .Lmwake3, r1
468 bsrf r1
469 nop
470.Lmwake3b:
471
4722:
473 /* Wake up all waiters to make sure no signal gets lost. */
9b2dc515
UD
474 tst r10, r10
475 bf/s 5f
476 mov r8, r4
7c370086 477 add #cond_futex, r4
07bd2a3f
UD
478 mov #FUTEX_WAKE, r5
479 mov #-1, r6
480 shlr r6 /* r6 = 0x7fffffff */
481 mov #0, r7
482 mov #SYS_futex, r3
483 extu.b r3, r3
484 trapa #0x14
485 SYSCALL_INST_PAD
486
9b2dc515 4875:
07bd2a3f
UD
488 mov.l .Lmlocki3, r1
489 bsrf r1
490 mov r9, r4
491.Lmlocki3b:
492
493.LcallUR:
494 mov.l .Lresume, r1
495#ifdef PIC
496 add r12, r1
497#endif
498 jsr @r1
499 mov r11, r4
500 sleep
501
502 .align 2
503.Lmwait3:
504 .long __lll_mutex_lock_wait-.Lmwait3b
505.Lmwake3:
506 .long __lll_mutex_unlock_wake-.Lmwake3b
507.Lmlocki3:
508 .long __pthread_mutex_cond_lock-.Lmlocki3b
509.Lresume:
510#ifdef PIC
511 .long _Unwind_Resume@GOTOFF
512#else
513 .long _Unwind_Resume
514#endif
515.LENDCODE:
516 .size __condvar_w_cleanup, .-__condvar_w_cleanup
517
518
519 .section .gcc_except_table,"a",@progbits
520.LexceptSTART:
521 .byte 0xff ! @LPStart format (omit)
522 .byte 0xff ! @TType format (omit)
523 .byte 0x0b ! call-site format
524 ! DW_EH_PE_sdata4
525 .uleb128 .Lcstend-.Lcstbegin
526.Lcstbegin:
527 .ualong .LcleanupSTART-.LSTARTCODE
528 .ualong .LcleanupEND-.LcleanupSTART
529 .ualong __condvar_w_cleanup-.LSTARTCODE
530 .uleb128 0
531 .ualong .LcallUR-.LSTARTCODE
532 .ualong .LENDCODE-.LcallUR
533 .ualong 0
534 .uleb128 0
535.Lcstend:
536
537 .section .eh_frame,"a",@progbits
538.LSTARTFRAME:
539 .ualong .LENDCIE-.LSTARTCIE ! Length of the CIE.
540.LSTARTCIE:
541 .ualong 0 ! CIE ID.
542 .byte 1 ! Version number.
543#ifdef SHARED
544 .string "zPLR" ! NUL-terminated augmentation
545 ! string.
546#else
547 .string "zPL" ! NUL-terminated augmentation
548 ! string.
549#endif
550 .uleb128 1 ! Code alignment factor.
551 .sleb128 -4 ! Data alignment factor.
552 .byte 0x11 ! Return address register
553 ! column.
554#ifdef SHARED
555 .uleb128 7 ! Augmentation value length.
556 .byte 0x9b ! Personality: DW_EH_PE_pcrel
557 ! + DW_EH_PE_sdata4
558 ! + DW_EH_PE_indirect
559 .ualong DW.ref.__gcc_personality_v0-.
560 .byte 0x1b ! LSDA Encoding: DW_EH_PE_pcrel
561 ! + DW_EH_PE_sdata4.
562 .byte 0x1b ! FDE Encoding: DW_EH_PE_pcrel
563 ! + DW_EH_PE_sdata4.
564#else
565 .uleb128 6 ! Augmentation value length.
566 .byte 0x0 ! Personality: absolute
567 .ualong __gcc_personality_v0
568 .byte 0x0 ! LSDA Encoding: absolute
569#endif
570 .byte 0x0c ! DW_CFA_def_cfa
571 .uleb128 0xf
572 .uleb128 0
573 .align 2
574.LENDCIE:
575
576 .ualong .LENDFDE-.LSTARTFDE ! Length of the FDE.
577.LSTARTFDE:
578 .ualong .LSTARTFDE-.LSTARTFRAME ! CIE pointer.
579#ifdef SHARED
580 .ualong .LSTARTCODE-. ! PC-relative start address
581 ! of the code.
582#else
583 .ualong .LSTARTCODE ! Start address of the code.
584#endif
585 .ualong .LENDCODE-.LSTARTCODE ! Length of the code.
586 .uleb128 4 ! Augmentation size
587#ifdef SHARED
588 .ualong .LexceptSTART-.
589#else
590 .ualong .LexceptSTART
591#endif
592 .byte 0x4
593 .ualong .Lpush_r8-.LSTARTCODE
594 .byte 0xe
595 .uleb128 4
596 .byte 0x88
597 .uleb128 1
598 .byte 0x4
599 .ualong .Lpush_r9-.Lpush_r8
600 .byte 0xe
601 .uleb128 8
602 .byte 0x89
603 .uleb128 2
604 .byte 0x4
605 .ualong .Lpush_r10-.Lpush_r9
606 .byte 0xe
607 .uleb128 12
608 .byte 0x8a
609 .uleb128 3
610 .byte 0x4
611 .ualong .Lpush_r11-.Lpush_r10
612 .byte 0xe
613 .uleb128 16
614 .byte 0x8b
615 .uleb128 4
616 .byte 0x4
617 .ualong .Lpush_r12-.Lpush_r11
618 .byte 0xe
619 .uleb128 20
620 .byte 0x8c
621 .uleb128 5
622 .byte 0x4
623 .ualong .Lpush_pr-.Lpush_r12
624 .byte 0xe
625 .uleb128 24
626 .byte 0x91
627 .uleb128 6
628 .byte 0x4
629 .ualong .Lalloc-.Lpush_pr
630 .byte 0xe
631 .uleb128 72
07bd2a3f
UD
632 .align 2
633.LENDFDE:
634
635#ifdef SHARED
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
639 .align 4
640 .type DW.ref.__gcc_personality_v0, @object
641 .size DW.ref.__gcc_personality_v0, 4
642DW.ref.__gcc_personality_v0:
643 .long __gcc_personality_v0
644#endif