about summary refs log tree commit diff
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.gz
glibc-4a17085f1589c5451d031995534e00e763364fb0.tar.xz
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 \