summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S220
1 files changed, 174 insertions, 46 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index c7df9bf86..5a897f6fe 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,13 +17,12 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
+#include <tcb-offsets.h>
+#include <bits/kernel-features.h>
#include "lowlevel-atomic.h"
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-
.text
/* int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) */
@@ -105,7 +104,7 @@ __pthread_cond_wait:
mov.l @(cond_futex,r8),r0
add r2, r0
mov.l r0,@(cond_futex,r8)
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8), r0
add r2, r0
mov.l r0, @(cond_nwaiters,r8)
@@ -137,7 +136,22 @@ __pthread_cond_wait:
mov.l r0, @r15
mov #0, r7
- mov #FUTEX_WAIT, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAIT, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAIT, r0
+ or r0, r5
+#endif
+99:
mov.l @(8,r15), r6
mov r8, r4
add #cond_futex, r4
@@ -195,7 +209,7 @@ __pthread_cond_wait:
mov.l r1,@(woken_seq+4,r8)
16:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -207,7 +221,7 @@ __pthread_cond_wait:
not r0, r0
cmp/eq #0, r0
bf/s 17f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -215,7 +229,22 @@ __pthread_cond_wait:
mov r8, r4
add #cond_nwaiters, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff0, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
@@ -249,6 +278,10 @@ __pthread_cond_wait:
rts
mov.l @r15+, r8
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff0:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
.Lmunlock0:
.long __pthread_mutex_unlock_usercnt-.Lmunlock0b
@@ -265,10 +298,17 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait0, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait0, r1
bsrf r1
mov r2, r4
-.Lmwait0b:
+.Lwait0b:
bra 2b
nop
3:
@@ -277,10 +317,16 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake0, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake0, r1
bsrf r1
- nop
-.Lmwake0b:
+ extu.b r5, r5
+.Lwake0b:
bra 4b
nop
@@ -290,10 +336,17 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait1, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait1, r1
bsrf r1
mov r2, r4
-.Lmwait1b:
+.Lwait1b:
bra 6b
nop
@@ -303,10 +356,16 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake1, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake1, r1
bsrf r1
- nop
-.Lmwake1b:
+ extu.b r5, r5
+.Lwake1b:
bra 11b
nop
@@ -325,26 +384,32 @@ __pthread_cond_wait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake2, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake2, r1
bsrf r1
- nop
-.Lmwake2b:
+ extu.b r5, r5
+.Lwake2b:
13:
bra 14b
mov.l @(12,r15), r0
.align 2
-.Lmwait0:
- .long __lll_mutex_lock_wait-.Lmwait0b
-.Lmwake0:
- .long __lll_mutex_unlock_wake-.Lmwake0b
-.Lmwait1:
- .long __lll_mutex_lock_wait-.Lmwait1b
-.Lmwake1:
- .long __lll_mutex_unlock_wake-.Lmwake1b
-.Lmwake2:
- .long __lll_mutex_unlock_wake-.Lmwake2b
+.Lwait0:
+ .long __lll_lock_wait-.Lwait0b
+.Lwake0:
+ .long __lll_unlock_wake-.Lwake0b
+.Lwait1:
+ .long __lll_lock_wait-.Lwait1b
+.Lwake1:
+ .long __lll_unlock_wake-.Lwake1b
+.Lwake2:
+ .long __lll_unlock_wake-.Lwake2b
.size __pthread_cond_wait, .-__pthread_cond_wait
weak_alias (__pthread_cond_wait, pthread_cond_wait)
@@ -368,10 +433,17 @@ __condvar_w_cleanup:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r6
+ mov #LLL_SHARED, r6
+99:
+ extu.b r6, r6
+ mov.l .Lwait3, r1
bsrf r1
mov r2, r4
-.Lmwait3b:
+.Lwait3b:
1:
mov.l @(broadcast_seq,r8), r0
@@ -382,6 +454,21 @@ __condvar_w_cleanup:
mov #1, r2
mov #0, r3
+ /* We increment the wakeup_seq counter only if it is lower than
+ total_seq. If this is not the case the thread was woken and
+ then canceled. In this case we ignore the signal. */
+ mov.l @(total_seq+4,r8), r0
+ mov.l @(wakeup_seq+4,r8), r1
+ cmp/hi r1, r0
+ bt/s 6f
+ cmp/hi r0, r1
+ bt 7f
+ mov.l @(total_seq,r8), r0
+ mov.l @(wakeup_seq,r8), r1
+ cmp/hs r0, r1
+ bt 7f
+
+6:
clrt
mov.l @(wakeup_seq,r8),r0
mov.l @(wakeup_seq+4,r8),r1
@@ -393,6 +480,7 @@ __condvar_w_cleanup:
add r2, r0
mov.l r0,@(cond_futex,r8)
+7:
clrt
mov.l @(woken_seq,r8),r0
mov.l @(woken_seq+4,r8),r1
@@ -402,7 +490,7 @@ __condvar_w_cleanup:
mov.l r1,@(woken_seq+4,r8)
3:
- mov #(1 << clock_bits), r2
+ mov #(1 << nwaiters_shift), r2
mov.l @(cond_nwaiters,r8),r0
sub r2, r0
mov.l r0,@(cond_nwaiters,r8)
@@ -415,7 +503,7 @@ __condvar_w_cleanup:
not r0, r0
cmp/eq #0, r0
bf/s 4f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -423,7 +511,22 @@ __condvar_w_cleanup:
mov r8, r4
add #cond_nwaiters, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #1, r6
mov #0, r7
mov #SYS_futex, r3
@@ -445,10 +548,16 @@ __condvar_w_cleanup:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake3, r1
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bf/s 99f
+ mov #LLL_PRIVATE, r5
+ mov #LLL_SHARED, r5
+99:
+ mov.l .Lwake3, r1
bsrf r1
- nop
-.Lmwake3b:
+ extu.b r5, r5
+.Lwake3b:
2:
/* Wake up all waiters to make sure no signal gets lost. */
@@ -456,7 +565,22 @@ __condvar_w_cleanup:
bf/s 5f
mov r8, r4
add #cond_futex, r4
- mov #FUTEX_WAKE, r5
+ mov.l @(dep_mutex,r8), r0
+ cmp/eq #-1, r0
+ bt/s 99f
+ mov #FUTEX_WAKE, r5
+#ifdef __ASSUME_PRIVATE_FUTEX
+ mov #(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), r5
+ extu.b r5, r5
+#else
+ stc gbr, r1
+ mov.w .Lpfoff1, r2
+ add r2, r1
+ mov.l @r1, r5
+ mov #FUTEX_WAKE, r0
+ or r0, r5
+#endif
+99:
mov #-1, r6
shlr r6 /* r6 = 0x7fffffff */
mov #0, r7
@@ -480,11 +604,15 @@ __condvar_w_cleanup:
mov r11, r4
sleep
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff1:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.align 2
-.Lmwait3:
- .long __lll_mutex_lock_wait-.Lmwait3b
-.Lmwake3:
- .long __lll_mutex_unlock_wake-.Lmwake3b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
+.Lwake3:
+ .long __lll_unlock_wake-.Lwake3b
.Lmlocki3:
.long __pthread_mutex_cond_lock-.Lmlocki3b
.Lresume: