aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-07-12 01:29:23 +0000
committerUlrich Drepper <drepper@redhat.com>2003-07-12 01:29:23 +0000
commit4a17085f1589c5451d031995534e00e763364fb0 (patch)
tree7c4d50a5c79d4d8a6adbe7f4729929bd20daaff6 /nptl
parent6080ecdf3cfc34b45bdfc7669f03359adc77d959 (diff)
downloadglibc-4a17085f1589c5451d031995534e00e763364fb0.tar
glibc-4a17085f1589c5451d031995534e00e763364fb0.tar.gz
glibc-4a17085f1589c5451d031995534e00e763364fb0.tar.bz2
glibc-4a17085f1589c5451d031995534e00e763364fb0.zip
Update.
2003-07-12 Kaz Kojima <kkojima@rr.iij4u.or.jp> * sysdeps/unix/sysv/linux/sh/socket.S: Save and restore the PR register across CENABLE and CDISABLE.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog20
-rw-r--r--nptl/sysdeps/sh/tcb-offsets.sym10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S88
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S61
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S7
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S64
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S58
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h7
11 files changed, 258 insertions, 82 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index f00ba09057..56a38b28fa 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,23 @@
+2003-07-12 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * sysdeps/sh/tcb-offsets.sym: Add RESULT, TID, CANCELHANDLING and
+ CLEANUP_JMP_BUF.
+ * sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Use more
+ registers as variables. Call __pthread_mutex_unlock_usercnt.
+ * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Store TID
+ not self pointer in __writer. Compare with TID to determine
+ deadlocks.
+ * sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/sh/sem_wait.S: Add cancellation support.
+ * sysdeps/unix/sysv/linux/sh/sem_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Define all the nice
+ macros also when compiling librt.
+
2003-07-11 Jakub Jelinek <jakub@redhat.com>
* Makefile (CFLAGS-pthread_once.c): Add -fexceptions
diff --git a/nptl/sysdeps/sh/tcb-offsets.sym b/nptl/sysdeps/sh/tcb-offsets.sym
index fcc549fed7..e96daf980f 100644
--- a/nptl/sysdeps/sh/tcb-offsets.sym
+++ b/nptl/sysdeps/sh/tcb-offsets.sym
@@ -1,6 +1,10 @@
#include <sysdep.h>
#include <tls.h>
-MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads)
-TLS_PRE_TCB_SIZE sizeof (struct pthread)
-MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
+RESULT offsetof (struct pthread, result)
+TID offsetof (struct pthread, tid)
+CANCELHANDLING offsetof (struct pthread, cancelhandling)
+CLEANUP_JMP_BUF offsetof (struct pthread, cleanup_jmp_buf)
+MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads)
+TLS_PRE_TCB_SIZE sizeof (struct pthread)
+MUTEX_FUTEX offsetof (pthread_mutex_t, __data.__lock)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 5de20dd799..e519bf6461 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -36,15 +36,17 @@
.type __pthread_cond_timedwait, @function
.align 5
__pthread_cond_timedwait:
- mov.l r12, @-r15
- mov.l r10, @-r15
- mov.l r9, @-r15
mov.l r8, @-r15
+ mov.l r9, @-r15
+ mov.l r10, @-r15
+ mov.l r11, @-r15
+ mov.l r12, @-r15
+ mov.l r13, @-r15
sts.l pr, @-r15
add #-64, r15
mov r4, r8
mov r5, r9
- mov r6, r10
+ mov r6, r13
/* Get internal lock. */
mov #1, r3
@@ -64,13 +66,16 @@ __pthread_cond_timedwait:
/* Unlock the mutex. */
mov.l .Lmunlock1, r1
+ mov #0, r5
bsrf r1
mov r9, r4
.Lmunlock1b:
tst r0, r0
- bf 16f
-
+ bt 0f
+ bra 16f
+ nop
+0:
mov #1, r2
mov #0, r3
@@ -93,7 +98,11 @@ __pthread_cond_timedwait:
mov.l .Lccleanup1, r5
#endif
mov r15, r4
- add #36, r4
+ add #32, r4
+
+ /* Prepare structure passed to cancellation handler. */
+ mov.l r8, @(4,r15)
+ mov.l r9, @(8,r15)
mov.l .Lccpush1, r1
bsrf r1
@@ -101,13 +110,8 @@ __pthread_cond_timedwait:
.Lccpush1b:
/* Get and store current wakeup_seq value. */
- mov.l @(wakeup_seq,r8), r0
- mov.l @(wakeup_seq+4,r8), r1
- mov.l r0, @(20,r15)
- mov.l r1, @(24,r15)
- /* Prepare structure passed to cancellation handler. */
- mov.l r9, @r15
- mov.l r8, @(4,r15)
+ mov.l @(wakeup_seq,r8), r10
+ mov.l @(wakeup_seq+4,r8), r11
/* Unlock. */
8:
@@ -125,23 +129,23 @@ __pthread_cond_timedwait:
bsrf r1
nop
.Lenable1b:
- mov.l r0, @(8,r15)
+ mov.l r0, @r15
/* Get current time. */
mov r15, r4
- add #12, r4
+ add #16, r4
mov #0, r5
mov #SYS_gettimeofday, r3
trapa #0x12
SYSCALL_INST_PAD
/* Compute relative timeout. */
- mov.l @(16,r15), r0
+ mov.l @(20,r15), r0
mov.w .L1k, r1
dmulu.l r0, r1 /* Milli seconds to nano seconds. */
- mov.l @r10, r2
- mov.l @(4,r10), r3
- mov.l @(12,r15), r0
+ mov.l @r13, r2
+ mov.l @(4,r13), r3
+ mov.l @(16,r15), r0
sts macl, r1
sub r0, r2
clrt
@@ -155,24 +159,24 @@ __pthread_cond_timedwait:
bf 13f /* Time is already up. */
/* Store relative timeout. */
- mov.l r2, @(12,r15)
- mov.l r3, @(16,r15)
+ mov.l r2, @(16,r15)
+ mov.l r3, @(20,r15)
mov r15, r7
- add #12, r7
+ add #16, r7
mov #FUTEX_WAIT, r5
- mov.l @(20,r15), r6
+ mov r10, r6
mov r8, r4
add #wakeup_seq, r4
mov #SYS_futex, r3
extu.b r3, r3
trapa #0x14
SYSCALL_INST_PAD
- mov.l r0, @(28,r15)
+ mov.l r0, @(12,r15)
mov.l .Ldisable1, r1
bsrf r1
- mov.l @(8,r15), r4
+ mov.l @r15, r4
.Ldisable1b:
/* Lock. */
@@ -191,14 +195,12 @@ __pthread_cond_timedwait:
mov.l @(wakeup_seq,r8), r2
mov.l @(wakeup_seq+4,r8), r3
- mov.l @(24,r15), r5
- cmp/hi r5, r3
+ cmp/hi r11, r3
bt 7f
- cmp/hi r3, r5
+ cmp/hi r3, r11
bt 15f
- mov.l @(20,r15), r5
- cmp/hs r2, r5
+ cmp/hs r2, r10
bt 15f
7:
cmp/hi r1, r3
@@ -208,7 +210,7 @@ __pthread_cond_timedwait:
cmp/hi r0, r2
bt 9f
15:
- mov.l @(28,r15),r0
+ mov.l @(12,r15),r0
cmp/eq #-ETIMEDOUT, r0
bf 8b
13:
@@ -224,11 +226,11 @@ __pthread_cond_timedwait:
mov.l r1,@(wakeup_seq+4,r8)
mov #ETIMEDOUT, r0
bra 14f
- mov.l r0, @(32,r15)
+ mov.l r0, @(24,r15)
9:
mov #0, r0
- mov.l r0, @(32,r15)
+ mov.l r0, @(24,r15)
14:
mov #1, r2
mov #0, r3
@@ -252,7 +254,7 @@ __pthread_cond_timedwait:
11:
/* Remove cancellation handler. */
mov r15, r4
- add #36, r4
+ add #32, r4
mov.l .Lcpop1, r1
bsrf r1
mov #0, r5
@@ -267,23 +269,25 @@ __pthread_cond_timedwait:
/* We return the result of the mutex_lock operation if it failed. */
tst r0, r0
bf 18f
- mov.l @(32,r15), r0
+ mov.l @(24,r15), r0
18:
add #64, r15
lds.l @r15+, pr
- mov.l @r15+, r8
- mov.l @r15+, r9
+ mov.l @r15+, r13
+ mov.l @r15+, r12
+ mov.l @r15+, r11
mov.l @r15+, r10
+ mov.l @r15+, r9
rts
- mov.l @r15+, r12
+ mov.l @r15+, r8
ret
.L1k:
.word 1000
.align 2
.Lmunlock1:
- .long __pthread_mutex_unlock_internal-.Lmunlock1b
+ .long __pthread_mutex_unlock_usercnt-.Lmunlock1b
#ifdef PIC
.Lgot1:
.long _GLOBAL_OFFSET_TABLE_
@@ -360,7 +364,7 @@ __pthread_cond_timedwait:
16:
/* The initial unlocking of the mutex failed. */
- mov.l r0, @(32,r15)
+ mov.l r0, @(24,r15)
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
@@ -379,7 +383,7 @@ __pthread_cond_timedwait:
.Lmwake4b:
17:
bra 18b
- mov.l @(32,r15), r0
+ mov.l @(24,r15), r0
.align 2
.Lmwait2:
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
index f4f0edb0e6..06b0f6243a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -133,9 +133,11 @@ __condvar_cleanup:
.type __pthread_cond_wait, @function
.align 5
__pthread_cond_wait:
- mov.l r12, @-r15
- mov.l r9, @-r15
mov.l r8, @-r15
+ mov.l r9, @-r15
+ mov.l r10, @-r15
+ mov.l r11, @-r15
+ mov.l r12, @-r15
sts.l pr, @-r15
add #-48, r15
mov r4, r8
@@ -149,21 +151,27 @@ __pthread_cond_wait:
XADD (r3, @r8, r2)
#endif
tst r2, r2
- bf 1f
+ bt 2f
+ bra 1f
+ nop
+2:
/* Store the reference to the mutex. If there is already a
different value in there this is a bad user bug. */
mov.l r9, @(dep_mutex,r8)
/* Unlock the mutex. */
mov.l .Lmunlock0, r1
+ mov #0, r5
bsrf r1
mov r9, r4
.Lmunlock0b:
tst r0, r0
- bf 12f
-
+ bt 0f
+ bra 12f
+ nop
+0:
mov #1, r2
mov #0, r3
@@ -186,7 +194,11 @@ __pthread_cond_wait:
mov.l .Lccleanup0, r5
#endif
mov r15, r4
- add #20, r4
+ add #16, r4
+
+ /* Prepare structure passed to cancellation handler. */
+ mov.l r8, @(4,r15)
+ mov.l r9, @(8,r15)
mov.l .Lccpush0, r1
bsrf r1
@@ -194,13 +206,8 @@ __pthread_cond_wait:
.Lccpush0b:
/* Get and store current wakeup_seq value. */
- mov.l @(wakeup_seq,r8), r0
- mov.l @(wakeup_seq+4,r8), r1
- mov.l r0, @(12,r15)
- mov.l r1, @(16,r15)
- /* Prepare structure passed to cancellation handler. */
- mov.l r9, @r15
- mov.l r8, @(4,r15)
+ mov.l @(wakeup_seq,r8), r10
+ mov.l @(wakeup_seq+4,r8), r11
8:
/* Unlock. */
@@ -216,11 +223,11 @@ __pthread_cond_wait:
bsrf r1
nop
.Lenable0b:
- mov.l r0, @(8,r15)
+ mov.l r0, @r15
mov #0, r7
mov #FUTEX_WAIT, r5
- mov.l @(12,r15), r6
+ mov r10, r6
mov r8, r4
add #wakeup_seq, r4
mov #SYS_futex, r3
@@ -230,7 +237,7 @@ __pthread_cond_wait:
mov.l .Ldisable0, r1
bsrf r1
- mov.l @(8,r15), r4
+ mov.l @r15, r4
.Ldisable0b:
/* Lock. */
@@ -249,14 +256,12 @@ __pthread_cond_wait:
mov.l @(wakeup_seq,r8), r2
mov.l @(wakeup_seq+4,r8), r3
- mov.l @(16,r15), r5
- cmp/hi r5, r3
+ cmp/hi r11, r3
bt 7f
- cmp/hi r3, r5
+ cmp/hi r3, r11
bt 8b
- mov.l @(12,r15), r5
- cmp/hs r2, r5
+ cmp/hs r2, r10
bt 8b
7:
cmp/hi r1, r3
@@ -288,7 +293,7 @@ __pthread_cond_wait:
11:
/* Remove cancellation handler. */
mov r15, r4
- add #20, r4
+ add #16, r4
mov.l .Lcpop0, r1
bsrf r1
mov #0, r5
@@ -304,14 +309,16 @@ __pthread_cond_wait:
14:
add #48, r15
lds.l @r15+, pr
- mov.l @r15+, r8
+ mov.l @r15+, r12
+ mov.l @r15+, r11
+ mov.l @r15+, r10
mov.l @r15+, r9
rts
- mov.l @r15+, r12
+ mov.l @r15+, r8
.align 2
.Lmunlock0:
- .long __pthread_mutex_unlock_internal-.Lmunlock0b
+ .long __pthread_mutex_unlock_usercnt-.Lmunlock0b
#ifdef PIC
.Lgot0:
.long _GLOBAL_OFFSET_TABLE_
@@ -385,7 +392,7 @@ __pthread_cond_wait:
12:
/* The initial unlocking of the mutex failed. */
- mov.l r0, @-r15
+ mov.l r0, @(12,r15)
#if cond_lock != 0
DEC (@(cond_lock,r8), r2)
#else
@@ -405,7 +412,7 @@ __pthread_cond_wait:
13:
bra 14b
- mov.l @r15+, r0
+ mov.l @(12,r15), r0
.align 2
.Lmwait0:
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
index 14da24ec86..bee9e9625e 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
@@ -137,12 +138,18 @@ __pthread_rwlock_rdlock:
nop
14:
stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
cmp/eq r1, r0
bf 3b
/* Deadlock detected. */
bra 9b
mov #EDEADLK, r3
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
6:
mov r8, r4
#if MUTEX != 0
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
index 5f1c1f739a..b43b576ef6 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
@@ -196,12 +197,18 @@ pthread_rwlock_timedrdlock:
nop
14:
stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
cmp/eq r1, r0
bf 3b
/* Deadlock detected. */
bra 9b
mov #EDEADLK, r3
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
6:
mov r8, r4
#if MUTEX != 0
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
index 36febf484e..14008279e3 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_gettimeofday __NR_gettimeofday
@@ -154,6 +155,8 @@ pthread_rwlock_timedwrlock:
5:
mov #0, r3
stc gbr, r0
+ mov.w .Ltidoff, r1
+ mov.l @(r0,r1), r0
mov.l r0, @(WRITER,r8)
9:
#if MUTEX == 0
@@ -193,6 +196,9 @@ pthread_rwlock_timedwrlock:
nop
14:
stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
cmp/eq r1, r0
bf 3b
bra 9b
@@ -209,6 +215,9 @@ pthread_rwlock_timedwrlock:
bra 7b
mov #0, r3
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
4:
/* Overflow. */
mov.l @(WRITERS_QUEUED,r8), r1
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
index b923c8846b..7b1fbcfa14 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
#define SYS_futex 240
@@ -99,6 +100,8 @@ __pthread_rwlock_wrlock:
5:
mov #0, r3
stc gbr, r0
+ mov.w .Ltidoff, r1
+ mov.l @(r0,r1), r0
mov.l r0, @(WRITER,r8)
9:
#if MUTEX == 0
@@ -130,6 +133,9 @@ __pthread_rwlock_wrlock:
nop
14:
stc gbr, r1
+ mov.w .Ltidoff, r2
+ add r2, r1
+ mov.l @r1, r1
cmp/eq r1, r0
bf 3b
bra 9b
@@ -146,6 +152,9 @@ __pthread_rwlock_wrlock:
bra 7b
mov #0, r3
+.Ltidoff:
+ .word TID - TLS_PRE_TCB_SIZE
+
4:
mov.l @(WRITERS_QUEUED,r8), r1
add #-1, r1
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
index b6d4d4c886..4832d4f358 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
@@ -33,6 +34,15 @@
.type sem_timedwait,@function
.align 5
sem_timedwait:
+ /* First check for cancellation. */
+ stc gbr, r0
+ mov.w .Lchand, r1
+ mov.l @(r0,r1), r0
+ mov #0xf9, r1
+ and r1, r0
+ cmp/eq #8, r0
+ bt 10f
+
mov.l @r4, r0
2:
tst r0, r0
@@ -48,9 +58,10 @@ sem_timedwait:
1:
/* Check whether the timeout value is valid. */
- mov.l r12, @-r15
- mov.l r9, @-r15
mov.l r8, @-r15
+ mov.l r9, @-r15
+ mov.l r10, @-r15
+ mov.l r12, @-r15
sts.l pr, @-r15
add #-8, r15
mov r4, r8
@@ -63,6 +74,12 @@ sem_timedwait:
bt/s 6f
mov #EINVAL, r0
7:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov r0, r10
+
/* Compute relative timeout. */
mov r15, r4
mov #0, r5
@@ -102,6 +119,13 @@ sem_timedwait:
trapa #0x14
SYSCALL_INST_PAD
+ mov.l .Ldisable0, r1
+ mov r10, r4
+ bsrf r1
+ mov r0, r10
+.Ldisable0b:
+ mov r10, r0
+
tst r0, r0
bt 9f
cmp/eq #-EWOULDBLOCK, r0
@@ -121,9 +145,10 @@ sem_timedwait:
add #8, r15
lds.l @r15+, pr
- mov.l @r15+, r8
- mov.l @r15+, r9
mov.l @r15+, r12
+ mov.l @r15+, r10
+ mov.l @r15+, r9
+ mov.l @r15+, r8
rts
mov #0, r0
@@ -150,14 +175,35 @@ sem_timedwait:
#endif
add #8, r15
lds.l @r15+, pr
- mov.l @r15+, r8
- mov.l @r15+, r9
mov.l @r15+, r12
+ mov.l @r15+, r10
+ mov.l @r15+, r9
+ mov.l @r15+, r8
rts
mov #-1, r0
+10:
+ /* Canceled. */
+ stc gbr, r0
+ mov.w .Lresult, r1
+ mov #-1, r2
+ mov.l r2, @(r0,r1)
+ mov.w .Lchand, r0
+ or.b #0x10, @(r0,gbr)
+ stc gbr, r0
+ mov.w .Lclbuf, r1
+ mov.l .Lunwind, r2
+ jmp @r2
+ mov.l @(r0,r1), r4
+
.L1k:
.word 1000
+.Lchand:
+ .word CANCELHANDLING - TLS_PRE_TCB_SIZE
+.Lresult:
+ .word RESULT - TLS_PRE_TCB_SIZE
+.Lclbuf:
+ .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
.align 2
.L1g:
.long 1000000000
@@ -170,4 +216,10 @@ sem_timedwait:
.Lerrloc2:
.long __errno_location@PLT-(.Lerrloc2b+2-.)
#endif
+.Lenable0:
+ .long __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+ .long __pthread_disable_asynccancel-.Ldisable0b
+.Lunwind:
+ .long __pthread_unwind
.size sem_timedwait,.-sem_timedwait
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
index 49b76c6d8c..8a55394c29 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <shlib-compat.h>
#include <pthread-errnos.h>
+#include <tcb-offsets.h>
#include "lowlevel-atomic.h"
@@ -33,8 +34,18 @@
.type __new_sem_wait,@function
.align 5
__new_sem_wait:
- mov.l r12, @-r15
+ /* First check for cancellation. */
+ stc gbr, r0
+ mov.w .Lchand, r1
+ mov.l @(r0,r1), r0
+ mov #0xf9, r1
+ and r1, r0
+ cmp/eq #8, r0
+ bt 5f
+
mov.l r8, @-r15
+ mov.l r10, @-r15
+ mov.l r12, @-r15
sts.l pr, @-r15
mov r4, r8
3:
@@ -48,12 +59,19 @@ __new_sem_wait:
CMPXCHG (r4, @r8, r3, r2)
bf 2b
lds.l @r15+, pr
- mov.l @r15+, r8
mov.l @r15+, r12
+ mov.l @r15+, r10
+ mov.l @r15+, r8
rts
mov #0, r0
1:
+ mov.l .Lenable0, r1
+ bsrf r1
+ nop
+.Lenable0b:
+ mov r0, r10
+
mov r8, r4
mov #FUTEX_WAIT, r5
mov #0, r6
@@ -63,6 +81,13 @@ __new_sem_wait:
trapa #0x14
SYSCALL_INST_PAD
+ mov.l .Ldisable0, r1
+ mov r10, r4
+ bsrf r1
+ mov r0, r10
+.Ldisable0b:
+ mov r10, r0
+
tst r0, r0
bt 3b
cmp/eq #-EWOULDBLOCK, r0
@@ -88,11 +113,32 @@ __new_sem_wait:
mov.l r8, @r0
#endif
lds.l @r15+, pr
- mov.l @r15+, r8
mov.l @r15+, r12
+ mov.l @r15+, r10
+ mov.l @r15+, r8
rts
mov #-1, r0
+5:
+ /* Canceled. */
+ stc gbr, r0
+ mov.w .Lresult, r1
+ mov #-1, r2
+ mov.l r2, @(r0,r1)
+ mov.w .Lchand, r0
+ or.b #0x10, @(r0,gbr)
+ stc gbr, r0
+ mov.w .Lclbuf, r1
+ mov.l .Lunwind, r2
+ jmp @r2
+ mov.l @(r0,r1), r4
+
+.Lchand:
+ .word CANCELHANDLING - TLS_PRE_TCB_SIZE
+.Lresult:
+ .word RESULT - TLS_PRE_TCB_SIZE
+.Lclbuf:
+ .word CLEANUP_JMP_BUF - TLS_PRE_TCB_SIZE
.align 2
.Lgot0:
.long _GLOBAL_OFFSET_TABLE_
@@ -103,5 +149,11 @@ __new_sem_wait:
.Lerrloc0:
.long __errno_location@PLT-(.Lerrloc0b+2-.)
#endif
+.Lenable0:
+ .long __pthread_enable_asynccancel-.Lenable0b
+.Ldisable0:
+ .long __pthread_disable_asynccancel-.Ldisable0b
+.Lunwind:
+ .long __pthread_unwind
.size __new_sem_wait,.-__new_sem_wait
versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index b7dcfc8c43..b783c98108 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -90,9 +90,14 @@
# ifdef IS_IN_libpthread
# define __local_enable_asynccancel __pthread_enable_asynccancel
# define __local_disable_asynccancel __pthread_disable_asynccancel
-# else
+# elif !defined NOT_IN_libc
# define __local_enable_asynccancel __libc_enable_asynccancel
# define __local_disable_asynccancel __libc_disable_asynccancel
+# elif defined IS_IN_librt
+# define __local_enable_asynccancel __librt_enable_asynccancel
+# define __local_disable_asynccancel __librt_disable_asynccancel
+# else
+# error Unsupported library
# endif
# define CENABLE \