summaryrefslogtreecommitdiff
path: root/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S')
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S184
1 files changed, 138 insertions, 46 deletions
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 5812488b2..3e117564f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.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,16 +17,13 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <pthread-errnos.h>
+#include <bits/kernel-features.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
-#define SYS_gettimeofday __NR_gettimeofday
-
-#define FUTEX_WAIT 0
-#define FUTEX_WAKE 1
-
-
.text
/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
@@ -119,7 +116,7 @@ __pthread_cond_timedwait:
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)
@@ -135,7 +132,7 @@ __pthread_cond_timedwait:
#ifdef __NR_clock_gettime
/* Get the clock number. */
mov.l @(cond_nwaiters,r8), r4
- mov #((1 << clock_bits) - 1), r0
+ mov #((1 << nwaiters_shift) - 1), r0
and r0, r4
/* Only clocks 0 and 1 are allowed. Both are handled in the
kernel. */
@@ -163,7 +160,7 @@ __pthread_cond_timedwait:
mov r15, r4
add #16, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -181,7 +178,7 @@ __pthread_cond_timedwait:
mov r15, r4
add #16, r4
mov #0, r5
- mov #SYS_gettimeofday, r3
+ mov #__NR_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
@@ -233,7 +230,22 @@ __pthread_cond_timedwait:
mov r15, r7
add #16, 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 .Lpfoff, 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
@@ -322,7 +334,7 @@ __pthread_cond_timedwait:
mov.l r1,@(woken_seq+4,r8)
24:
- 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)
@@ -334,7 +346,7 @@ __pthread_cond_timedwait:
not r0, r0
cmp/eq #0, r0
bf/s 25f
- mov #((1 << clock_bits) - 1), r1
+ mov #((1 << nwaiters_shift) - 1), r1
not r1, r1
mov.l @(cond_nwaiters,r8),r0
tst r1, r0
@@ -342,7 +354,22 @@ __pthread_cond_timedwait:
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 .Lpfoff, 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
@@ -382,6 +409,10 @@ __pthread_cond_timedwait:
rts
mov.l @r15+, r8
+#ifndef __ASSUME_PRIVATE_FUTEX
+.Lpfoff:
+ .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
+#endif
.L1k:
.word 1000
.align 2
@@ -402,10 +433,17 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait2, 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 .Lwait2, r1
bsrf r1
mov r2, r4
-.Lmwait2b:
+.Lwait2b:
bra 2b
nop
@@ -415,10 +453,16 @@ __pthread_cond_timedwait:
#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 .Lmwait2, r1
bsrf r1
- nop
-.Lmwake2b:
+ extu.b r5, r5
+.Lmwait2b:
bra 4b
nop
@@ -428,10 +472,17 @@ __pthread_cond_timedwait:
#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:
bra 6b
nop
@@ -441,10 +492,16 @@ __pthread_cond_timedwait:
#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 .Lmwait3, r1
bsrf r1
- nop
-.Lmwake3b:
+ extu.b r5, r5
+.Lmwait3b:
bra 11b
nop
@@ -463,25 +520,31 @@ __pthread_cond_timedwait:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake4, 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 .Lmwait4, r1
bsrf r1
- nop
-.Lmwake4b:
+ extu.b r5, r5
+.Lmwait4b:
17:
bra 18b
mov.l @(24,r15), r0
.align 2
+.Lwait2:
+ .long __lll_lock_wait-.Lwait2b
.Lmwait2:
- .long __lll_mutex_lock_wait-.Lmwait2b
-.Lmwake2:
- .long __lll_mutex_unlock_wake-.Lmwake2b
+ .long __lll_unlock_wake-.Lmwait2b
+.Lwait3:
+ .long __lll_lock_wait-.Lwait3b
.Lmwait3:
- .long __lll_mutex_lock_wait-.Lmwait3b
-.Lmwake3:
- .long __lll_mutex_unlock_wake-.Lmwake3b
-.Lmwake4:
- .long __lll_mutex_unlock_wake-.Lmwake4b
+ .long __lll_unlock_wake-.Lmwait3b
+.Lmwait4:
+ .long __lll_unlock_wake-.Lmwait4b
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait)
@@ -505,10 +568,17 @@ __condvar_tw_cleanup:
#if cond_lock != 0
add #cond_lock, r5
#endif
- mov.l .Lmwait5, 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 .Lwait5, r1
bsrf r1
mov r2, r4
-.Lmwait5b:
+.Lwait5b:
1:
mov.l @(broadcast_seq,r8), r0
@@ -519,6 +589,21 @@ __condvar_tw_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
@@ -530,6 +615,7 @@ __condvar_tw_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
@@ -539,7 +625,7 @@ __condvar_tw_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)
@@ -552,7 +638,7 @@ __condvar_tw_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
@@ -582,10 +668,16 @@ __condvar_tw_cleanup:
#if cond_lock != 0
add #cond_lock, r4
#endif
- mov.l .Lmwake5, 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 .Lmwait5, r1
bsrf r1
- nop
-.Lmwake5b:
+ extu.b r5, r5
+.Lmwait5b:
2:
/* Wake up all waiters to make sure no signal gets lost. */
@@ -618,10 +710,10 @@ __condvar_tw_cleanup:
sleep
.align 2
+.Lwait5:
+ .long __lll_lock_wait-.Lwait5b
.Lmwait5:
- .long __lll_mutex_lock_wait-.Lmwait5b
-.Lmwake5:
- .long __lll_mutex_unlock_wake-.Lmwake5b
+ .long __lll_unlock_wake-.Lmwait5b
.Lmlocki5:
.long __pthread_mutex_cond_lock-.Lmlocki5b
.Lresume: