about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog33
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S34
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S94
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S102
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S25
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S35
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S54
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S15
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_post.S4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S2
15 files changed, 315 insertions, 110 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 3bf0064ce6..0724d7214f 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,36 @@
+2003-03-28  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/sh/tls.h: Include nptl/descr.h after the definition
+	of TLS_DTV_AT_TP.
+	(INSTALL_DTV): Add parens.
+	(THREAD_GETMEM, THREAD_GETMEM_NC, THREAD_SETMEM, THREAD_SETMEM_NC):
+	Use passed descr instead of THREAD_SELF.
+	* sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
+	(__lll_mutex_timedlock_wait): Correct expected value after
+	spurious wakeup.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S:
+	Release lock before waking up the waiters.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S: Correct exit
+	criteria.  Reorderstruct passed to cleanup handler.  Fix
+	handling of cancellation and failung pthread_mutex_unlock call.
+	Use __pthread_enable_asynccancel_2 instead of
+	__pthread_enable_asynccancel.
+	* sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+	Return result of lock re-get if it fails.
+	* sysdeps/unix/sysv/linux/sh/pthread_once.S: Fix wrong argument
+	for __pthread_cleanup_push.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S: Fix
+	completely broken rwlock implementation.
+	* 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/pthread_rwlock_unlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S: Likewise.
+	* sysdeps/unix/sysv/linux/sh/sem_post.S: Fix error value.  Use
+	versioned_symbol macro.
+	* sysdeps/unix/sysv/linux/sh/sem_trywait.S: Use	versioned_symbol macro.
+	* sysdeps/unix/sysv/linux/sh/sem_wait.S: Likewise.
+
 2003-03-27  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/kernel-posix-timers.h: Don't declare
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index ecb0059036..115c5292dd 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -177,8 +177,6 @@ __lll_timedwait_tid:
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
-	mov	r0, r1
-
 	mov.l	@r8, r0
 	tst	r0, r0
 	bf	1f
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
index 6df513cbec..0aa2048d11 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelmutex.S
@@ -73,12 +73,13 @@ __lll_mutex_timedlock_wait:
 	mov	r5, r8
 	mov	r6, r9
 	mov	r4, r10
-	add	#1, r10
 
 	/* Stack frame for the timespec and timeval structs.  */
 	add	#-8, r15
 
 1:
+	add	#1, r10
+
 	/* Get current time.  */
 	mov	r15, r4
 	mov	#0, r5
@@ -116,10 +117,11 @@ __lll_mutex_timedlock_wait:
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
+	mov	r0, r4
 
-	mov	#1, r3
-	XADD (r3, @r8, r10)
-	tst	r10, r10
+	mov	#1, r10
+	XADD (r10, @r8, r3)
+	tst	r3, r3
 	bf	7f
 
 	mov	#2, r1
@@ -134,7 +136,7 @@ __lll_mutex_timedlock_wait:
 7:
 	/* Check whether the time expired.  */
 	mov	#-ETIMEDOUT, r1
-	cmp/eq	r0, r1
+	cmp/eq	r4, r1
 	bt	5f
 	bra	1b
 	 nop
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
index 93818f96df..8dd31aac29 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_broadcast.S
@@ -59,10 +59,20 @@ __pthread_cond_broadcast:
 	bf	4f
 
 3:
-	/* Case all currently waiting threads to wake up.  */
+	/* Cause all currently waiting threads to recognize they are
+	   woken up.  */
 	mov.l	r1, @(wakeup_seq,r8)
 	mov.l	r0, @(wakeup_seq+4,r8)
 
+	/* Unlock.  */
+#if cond_lock != 0
+	DEC (@(cond_lock,r8), r2)
+#else
+	DEC (@r8, r2)
+#endif
+	tst	r2, r2
+	bf	7f
+8:
 	/* Wake up all threads.  */
 	mov	r8, r4
 	add	#wakeup_seq, r4
@@ -75,6 +85,11 @@ __pthread_cond_broadcast:
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
+	mov	#0, r0
+	lds.l	@r15+, pr
+	rts
+	 mov.l	@r15+, r8
+
 4:
 	/* Unlock.  */
 #if cond_lock != 0
@@ -104,7 +119,7 @@ __pthread_cond_broadcast:
 	 nop
 
 5:
-	/* Unlock in loop requires waekup.  */
+	/* Unlock in loop requires wakeup.  */
 	mov	r8, r4
 #if cond_lock != 0
 	add	#cond_lock, r4
@@ -116,11 +131,26 @@ __pthread_cond_broadcast:
 	bra	6b
 	 nop
 
+7:
+	/* Unlock in loop requires wakeup.  */
+	mov	r8, r4
+#if cond_lock != 0
+	add	#cond_lock, r4
+#endif
+	mov.l	.Lmwake6, r1
+	bsrf	r1
+	 nop
+.Lmwake6b:
+	bra	8b
+	 nop
+
 	.align	2
 .Lmwait5:
 	.long	__lll_mutex_lock_wait-.Lmwait5b
 .Lmwake5:
 	.long	__lll_mutex_unlock_wake-.Lmwake5b
+.Lmwake6:
+	.long	__lll_mutex_unlock_wake-.Lmwake6b
 	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast
 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
 		  GLIBC_2_3_2)
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 59aeff70fb..6ad987d005 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -41,7 +41,7 @@ __pthread_cond_timedwait:
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
-	add	#-48, r15
+	add	#-64, r15
 	mov	r4, r8
 	mov	r5, r9
 	mov	r6, r10
@@ -64,6 +64,9 @@ __pthread_cond_timedwait:
 	 mov	r9, r4
 .Lmunlock1b:
 
+	tst	r0, r0
+	bf	16f
+
 	mov	#1, r2
 	mov	#0, r3
 
@@ -86,18 +89,21 @@ __pthread_cond_timedwait:
 	mov.l	.Lccleanup1, r5
 #endif
 	mov	r15, r4
-	add	#28, r4
+	add	#36, r4
 
 	mov.l	.Lccpush1, r1
 	bsrf	r1
-	 mov	r8, r6
+	 mov	r15, r6
 .Lccpush1b:
 
 	/* 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)
+	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)
 
 	/* Unlock.  */
 8:
@@ -111,27 +117,28 @@ __pthread_cond_timedwait:
 	bra	3f
 	 nop
 4:
+	mov	r15, r4
 	mov.l	.Lenable1, r1
 	bsrf	r1
-	 nop
+	 add	#8, r4
+
 .Lenable1b:
-	mov.l	r0, @r15
 
 	/* Get current time.  */
 	mov	r15, r4
-	add	#4, r4
+	add	#12, r4
 	mov	#0, r5
 	mov	#SYS_gettimeofday, r3
 	trapa	#0x12
 	SYSCALL_INST_PAD
 
 	/* Compute relative timeout.  */
-	mov.l	@(8,r15), r0
+	mov.l	@(16,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	@(4,r15), r0
+	mov.l	@(12,r15), r0
 	sts	macl, r1
 	sub	r0, r2
 	clrt
@@ -145,24 +152,24 @@ __pthread_cond_timedwait:
 	bf	13f		/* Time is already up.  */
 
 	/* Store relative timeout.  */
-	mov.l	r2, @(4,r15)
-	mov.l	r3, @(8,r15)
+	mov.l	r2, @(12,r15)
+	mov.l	r3, @(16,r15)
 
 	mov	r15, r7
-	add	#4, r7
+	add	#12, r7
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(12,r15), r6
+	mov.l	@(20,r15), r6
 	mov	r8, r4
 	add	#wakeup_seq, r4
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
-	mov.l	r0, @(20,r15)
+	mov.l	r0, @(28,r15)
 
 	mov.l	.Ldisable1, r1
 	bsrf	r1
-	 mov.l	@r15, r4
+	 mov.l	@(8,r15), r4
 .Ldisable1b:
 
 	/* Lock.  */
@@ -181,14 +188,14 @@ __pthread_cond_timedwait:
 	mov.l	@(wakeup_seq,r8), r2
 	mov.l	@(wakeup_seq+4,r8), r3
 
-	mov.l	@(16,r15), r5
-	cmp/hi	r5, r1
+	mov.l	@(24,r15), r5
+	cmp/hi	r5, r3
 	bt	7f
-	cmp/hi	r1, r5
+	cmp/hi	r3, r5
 	bt	15f
 
-	mov.l	@(12,r15), r5
-	cmp/hi	r0, r5
+	mov.l	@(20,r15), r5
+	cmp/hs	r2, r5
 	bt	15f
 7:
 	cmp/hi	r1, r3
@@ -198,7 +205,7 @@ __pthread_cond_timedwait:
 	cmp/hi	r0, r2
 	bt	9f
 15:
-	mov.l	@(20,r15),r0
+	mov.l	@(28,r15),r0
 	cmp/eq	#-ETIMEDOUT, r0
 	bf	8b
 13:
@@ -214,11 +221,11 @@ __pthread_cond_timedwait:
 	mov.l	r1,@(wakeup_seq+4,r8)
 	mov	#ETIMEDOUT, r0
 	bra	14f
-	 mov.l	r0, @(24,r15)
+	 mov.l	r0, @(32,r15)
 
 9:
 	mov	#0, r0
-	mov.l	r0, @(24,r15)
+	mov.l	r0, @(32,r15)
 14:
 	mov	#1, r2
 	mov	#0, r3
@@ -242,7 +249,7 @@ __pthread_cond_timedwait:
 11:
 	/* Remove cancellation handler.  */
 	mov	r15, r4
-	add	#28, r4
+	add	#36, r4
 	mov.l	.Lcpop1, r1
 	bsrf	r1
 	 mov	#0, r5
@@ -254,11 +261,13 @@ __pthread_cond_timedwait:
 	 mov	#0, r5
 .Lmlocki1b:
 
-	mov.l	@(24,r15), r0
+	/* We return the result of the mutex_lock operation if it failed.  */
+	tst	r0, r0
+	bf	18f
+	mov.l	@(32,r15), r0
 
-	add	#48, r15
-
-	/* We return the result of the mutex_lock operation.  */
+18:	
+	add	#64, r15
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
@@ -284,7 +293,7 @@ __pthread_cond_timedwait:
 .Lccpush1:
 	.long	__pthread_cleanup_push-.Lccpush1b
 .Lenable1:
-	.long	__pthread_enable_asynccancel-.Lenable1b
+	.long	__pthread_enable_asynccancel_2-.Lenable1b
 .Ldisable1:
 	.long	__pthread_disable_asynccancel-.Ldisable1b
 .Lcpop1:
@@ -346,6 +355,29 @@ __pthread_cond_timedwait:
 	bra	11b
 	 nop
 
+16:
+	/* The initial unlocking of the mutex failed.  */
+	mov.l	r0, @(32,r15)
+#if cond_lock != 0
+	DEC (@(cond_lock,r8), r2)
+#else
+	DEC (@r8, r2)
+#endif
+	tst	r2, r2
+	bf	17f
+
+	mov	r8, r4
+#if cond_lock != 0
+	add	#cond_lock, r4
+#endif
+	mov.l	.Lmwake4, r1
+	bsrf	r1
+	 nop
+.Lmwake4b:
+17:
+	bra	18b
+	 mov.l	@(32,r15), r0
+
 	.align	2
 .Lmwait2:
 	.long	__lll_mutex_lock_wait-.Lmwait2b
@@ -355,6 +387,8 @@ __pthread_cond_timedwait:
 	.long	__lll_mutex_lock_wait-.Lmwait3b
 .Lmwake3:
 	.long	__lll_mutex_unlock_wake-.Lmwake3b
+.Lmwake4:
+	.long	__lll_mutex_unlock_wake-.Lmwake4b
 	.size	__pthread_cond_timedwait, .-__pthread_cond_timedwait
 versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
 		  GLIBC_2_3_2)
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 342e78ed6e..a32df21f29 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
@@ -34,8 +34,10 @@
 	.hidden	__condvar_cleanup
 __condvar_cleanup:
 	mov.l	r8, @-r15
+	mov.l	r9, @-r15
 	sts.l	pr, @-r15
-	mov	r4, r8
+	mov	r4, r9
+	mov.l	@(4,r9), r8
 
 	/* Get internal lock.  */
 	mov	#1, r3
@@ -93,7 +95,33 @@ __condvar_cleanup:
 	 nop
 .Lwake0b:
 2:
+
+	/* Wake up all waiters to make sure no signal gets lost.  */
+	mov	r8, r4
+	add	#wakeup_seq, r4
+	mov	#FUTEX_WAKE, r5
+	mov	#-1, r6
+	shlr	r6		/* r6 = 0x7fffffff */
+	mov	#0, r7
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x14
+	SYSCALL_INST_PAD
+
+	/* Lock the mutex unless asynchronous cancellation is in effect.  */
+	mov.l	@(8,r9), r0
+	and	#2, r0
+	tst	r0, r0
+	bf	3f
+
+	mov.l	.Lmlocki1, r1
+	bsrf	r1
+	 mov.l	@r9, r4
+.Lmlocki1b:
+
+3:
 	lds.l	@r15+, pr
+	mov.l	@r15+, r9
 	rts
 	 mov.l	@r15+, r8
 
@@ -102,6 +130,8 @@ __condvar_cleanup:
 	.long	__lll_mutex_lock_wait-.Lwait0b
 .Lwake0:
 	.long	__lll_mutex_unlock_wake-.Lwake0b
+.Lmlocki1:
+	.long	__pthread_mutex_lock_internal-.Lmlocki1b
 	.size	__condvar_cleanup, .-__condvar_cleanup
 
 
@@ -114,7 +144,7 @@ __pthread_cond_wait:
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	sts.l	pr, @-r15
-	add	#-32, r15
+	add	#-48, r15
 	mov	r4, r8
 	mov	r5, r9
 
@@ -134,6 +164,9 @@ __pthread_cond_wait:
 	 mov	r9, r4
 .Lmunlock0b:
 
+	tst	r0, r0
+	bf	12f
+
 	mov	#1, r2
 	mov	#0, r3
 
@@ -156,18 +189,21 @@ __pthread_cond_wait:
 	mov.l	.Lccleanup0, r5
 #endif
 	mov	r15, r4
-	add	#12, r4
+	add	#20, r4
 
 	mov.l	.Lccpush0, r1
 	bsrf	r1
-	 mov	r8, r6
+	 mov	r15, r6
 .Lccpush0b:
 
 	/* Get and store current wakeup_seq value.  */
 	mov.l	@(wakeup_seq,r8), r0
 	mov.l	@(wakeup_seq+4,r8), r1
-	mov.l	r0, @(4,r15)
-	mov.l	r1, @(8,r15)
+	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)
 
 8:
 	/* Unlock.  */
@@ -179,15 +215,15 @@ __pthread_cond_wait:
 	tst	r2, r2
 	bf	3f
 4:
+	mov	r15, r4
 	mov.l	.Lenable0, r1
 	bsrf	r1
-	 nop
+	 add	#8, r4
 .Lenable0b:
-	mov.l	r0, @r15
 
 	mov	#0, r7
 	mov	#FUTEX_WAIT, r5
-	mov.l	@(4,r15), r6
+	mov.l	@(12,r15), r6
 	mov	r8, r4
 	add	#wakeup_seq, r4
 	mov	#SYS_futex, r3
@@ -197,7 +233,7 @@ __pthread_cond_wait:
 
 	mov.l	.Ldisable0, r1
 	bsrf	r1
-	 mov.l	@r15, r4
+	 mov.l	@(8,r15), r4
 .Ldisable0b:	
 
 	/* Lock.  */
@@ -216,14 +252,14 @@ __pthread_cond_wait:
 	mov.l	@(wakeup_seq,r8), r2
 	mov.l	@(wakeup_seq+4,r8), r3
 
-	mov.l	@(8,r15), r5
-	cmp/hi	r5, r1
+	mov.l	@(16,r15), r5
+	cmp/hi	r5, r3
 	bt	7f
-	cmp/hi	r1, r5
+	cmp/hi	r3, r5
 	bt	8b
 
-	mov.l	@(4,r15), r5
-	cmp/hi	r0, r5
+	mov.l	@(12,r15), r5
+	cmp/hs	r2, r5
 	bt	8b
 7:
 	cmp/hi	r1, r3
@@ -255,7 +291,7 @@ __pthread_cond_wait:
 11:
 	/* Remove cancellation handler.  */
 	mov	r15, r4
-	add	#12, r4
+	add	#20, r4
 	mov.l	.Lcpop0, r1
 	bsrf	r1
 	 mov	#0, r5
@@ -266,10 +302,10 @@ __pthread_cond_wait:
 	bsrf	r1
 	 mov	#0, r5
 .Lmlocki0b:
-
-	add	#32, r15
-
 	/* We return the result of the mutex_lock operation.  */
+
+14:
+	add	#48, r15
 	lds.l	@r15+, pr
 	mov.l	@r15+, r8
 	mov.l	@r15+, r9
@@ -291,7 +327,7 @@ __pthread_cond_wait:
 .Lccpush0:
 	.long	__pthread_cleanup_push-.Lccpush0b
 .Lenable0:
-	.long	__pthread_enable_asynccancel-.Lenable0b
+	.long	__pthread_enable_asynccancel_2-.Lenable0b
 .Ldisable0:
 	.long	__pthread_disable_asynccancel-.Ldisable0b
 .Lcpop0:
@@ -350,6 +386,30 @@ __pthread_cond_wait:
 	bra	11b
 	 nop
 
+12:
+	/* The initial unlocking of the mutex failed.  */
+	mov.l	r0, @-r15
+#if cond_lock != 0
+	DEC (@(cond_lock,r8), r2)
+#else
+	DEC (@r8, r2)
+#endif
+	tst	r2, r2
+	bf	13f
+
+	mov	r8, r4
+#if cond_lock != 0
+	add	#cond_lock, r4
+#endif
+	mov.l	.Lmwake2, r1
+	bsrf	r1
+	 nop
+.Lmwake2b:
+
+13:
+	bra	14b
+	 mov.l	@r15+, r0
+
 	.align	2
 .Lmwait0:
 	.long	__lll_mutex_lock_wait-.Lmwait0b
@@ -359,6 +419,8 @@ __pthread_cond_wait:
 	.long	__lll_mutex_lock_wait-.Lmwait1b
 .Lmwake1:
 	.long	__lll_mutex_unlock_wake-.Lmwake1b
+.Lmwake2:
+	.long	__lll_mutex_unlock_wake-.Lmwake2b
 	.size	__pthread_cond_wait, .-__pthread_cond_wait
 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
 		  GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
index c17701cffc..c292af02c0 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S
@@ -122,7 +122,7 @@ __pthread_once:
 #endif
 	mov.l	.Lcpush, r1
 	bsrf	r1
-	 mov	r3, r6
+	 mov	r9, r6
 .Lcpush0:
 	jsr	@r8
 	 nop
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 1aa1c72bbf..27aecad314 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_rdlock.S
@@ -75,7 +75,8 @@ __pthread_rwlock_rdlock:
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
 	mov	#FUTEX_WAIT, r5
-	mov	#0, r6
+	mov.l	@(READERS_WAKEUP,r8), r6
+	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
@@ -93,11 +94,8 @@ __pthread_rwlock_rdlock:
 13:
 	mov.l	@(READERS_QUEUED,r8), r0
 	add	#-1, r0
-	mov.l	r0, @(READERS_QUEUED,r8)
-	tst	r0, r0
-	bf	2b
 	bra	2b
-	 mov.l	r0, @(READERS_WAKEUP,r8)
+	 mov.l	r0, @(READERS_QUEUED,r8)
 
 5:
 	mov	#0, r3
@@ -138,7 +136,6 @@ __pthread_rwlock_rdlock:
 	stc	gbr, r1
 	mov.w	.Ltcboff,r2
 	sub	r2,r1
-	mov.l	@(8,r1),r1
 	cmp/eq	r1, r0
 	bf	3b
 	/* Deadlock detected.  */
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 84b5cdda3b..6f3f67e07b 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedrdlock.S
@@ -62,6 +62,12 @@ pthread_rwlock_timedrdlock:
 	tst	r0, r0
 	bt	5f
 3:
+	/* Check the value of the timeout parameter.  */
+	mov.l	.L1g0, r1
+	mov.l	@(4,r9), r0
+	cmp/hs	r1, r0
+	bt	19f
+
 	mov.l	@(READERS_QUEUED,r8), r0
 	add	#1, r0
 	mov.l	r0, @(READERS_QUEUED,r8)
@@ -109,7 +115,7 @@ pthread_rwlock_timedrdlock:
 	/* Futex call.  */
 	mov	r15, r7
 	mov	#FUTEX_WAIT, r5
-	mov	#0, r6
+	mov.l	@(READERS_WAKEUP,r8), r6
 	mov	r8, r4
 	add	#READERS_WAKEUP, r4
 	mov	#SYS_futex, r3
@@ -131,16 +137,16 @@ pthread_rwlock_timedrdlock:
 	bf	12f
 
 13:
-	mov	#-ETIMEDOUT, r0
-	cmp/eq	r0, r3
-	bt	18f
 	mov.l	@(READERS_QUEUED,r8), r0
 	add	#-1, r0
 	mov.l	r0, @(READERS_QUEUED,r8)
-	tst	r0, r0
+	mov	#-ETIMEDOUT, r0
+	cmp/eq	r0, r3
 	bf	2b
-	bra	2b
-	 mov.l	r0, @(READERS_WAKEUP,r8)
+
+18:
+	bra	9f
+	 mov	#ETIMEDOUT, r3
 
 5:
 	mov	#0, r3
@@ -189,7 +195,6 @@ pthread_rwlock_timedrdlock:
 	stc	gbr, r1
 	mov.w	.Ltcboff,r2
 	sub	r2,r1
-	mov.l	@(8,r1),r1
 	cmp/eq	r1, r0
 	bf	3b
 	/* Deadlock detected.  */
@@ -253,9 +258,9 @@ pthread_rwlock_timedrdlock:
 	bra	17b
 	 mov	#-ETIMEDOUT, r3
 
-18:
+19:
 	bra	9b
-	 mov	#ETIMEDOUT, r3
+	 mov	#EINVAL, r3
 
 .Ltcboff:
 	.word	TLS_PRE_TCB_SIZE
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 60ff48f90a..89bdc76d37 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_timedwrlock.S
@@ -59,6 +59,12 @@ pthread_rwlock_timedwrlock:
 	tst	r0, r0
 	bt	5f
 3:
+	/* Check the value of the timeout parameter.  */
+	mov.l	.L1g1, r1
+	mov.l	@(4,r9), r0
+	cmp/hs	r1, r0
+	bt	19f
+
 	mov.l	@(WRITERS_QUEUED,r8), r0
 	add	#1, r0
 	mov.l	r0, @(WRITERS_QUEUED,r8)
@@ -106,7 +112,7 @@ pthread_rwlock_timedwrlock:
 	/* Futex call.  */
 	mov	r15, r7
 	mov	#FUTEX_WAIT, r5
-	mov	#0, r6
+	mov.l	@(WRITERS_WAKEUP,r8), r6
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
 	mov	#SYS_futex, r3
@@ -128,22 +134,26 @@ pthread_rwlock_timedwrlock:
 	bf	12f
 
 13:
-	mov	#-ETIMEDOUT, r0
-	cmp/eq	r0, r3
-	bt	18f
 	mov.l	@(WRITERS_QUEUED,r8), r0
 	add	#-1, r0
 	mov.l	r0, @(WRITERS_QUEUED,r8)
-	mov	#0, r0
-	bra	2b
-	 mov.l	r0, @(WRITERS_WAKEUP,r8)
+	mov	#-ETIMEDOUT, r0
+	cmp/eq	r0, r3
+	bf	2b
+
+18:
+	bra	9f
+	 mov	#ETIMEDOUT, r3
+
+19:
+	bra	9f
+	 mov	#EINVAL, r3
 
 5:
 	mov	#0, r3
-	stc	gbr, r1
+	stc	gbr, r0
 	mov.w	.Ltcboff,r2
-	sub	r2,r1
-	mov.l	@(8,r1),r0
+	sub	r2,r0
 	mov.l	r0, @(WRITER,r8)
 9:
 #if MUTEX == 0
@@ -184,7 +194,6 @@ pthread_rwlock_timedwrlock:
 	stc	gbr, r1
 	mov.w	.Ltcboff,r2
 	sub	r2,r1
-	mov.l	@(8,r1),r1
 	cmp/eq	r1, r0
 	bf	3b
 	bra	9b
@@ -238,10 +247,6 @@ pthread_rwlock_timedwrlock:
 	bra	17b
 	 mov	#-ETIMEDOUT, r3
 
-18:
-	bra	9b
-	 mov	#ETIMEDOUT, r3
-
 .Ltcboff:
 	.word	TLS_PRE_TCB_SIZE
 	.align	2
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
index af046aad47..8303a984ae 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_unlock.S
@@ -57,24 +57,48 @@ __pthread_rwlock_unlock:
 5:
 	mov	#0, r0
 	mov.l	r0, @(WRITER,r8)
+	mov	#1, r6
 	mov	r8, r4
+	add	#WRITERS_WAKEUP, r4
 	mov.l	@(WRITERS_QUEUED,r8), r0
 	tst	r0, r0
-	bf	9f
+	bf	0f
+
+	/* If also no readers waiting nothing to do.  */
+	mov.l	@(READERS_QUEUED,r8), r0
+	tst	r0, r0
+	bt	6f
+
 	mov	#-1, r6
 	shlr	r6		/* r6 = 0x7fffffff */
-	bra	0f
-	 add	#READERS_WAKEUP, r4
-9:
-	mov	#1, r6
-	add	#WRITERS_WAKEUP, r4
+	mov	r8, r4
+	add	#READERS_WAKEUP, r4
+
 0:
+	mov.l	@r4, r0
+	add	#1, r0
+	mov.l	r0, @r4
+#if MUTEX == 0
+	DEC (@r8, r2)
+#else
+	DEC (@(MUTEX,r8), r2)
+#endif
+	tst	r2, r2
+	bf	7f
+
+8:
 	mov	#FUTEX_WAKE, r5
 	mov	#SYS_futex, r3
+	mov	#0, r7
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
+	lds.l	@r15+, pr
+	mov.l	@r15+, r8
+	mov.l	@r15+, r12
+	rts
+	 mov	#0, r0
 6:
 #if MUTEX == 0
 	DEC (@r8, r2)
@@ -114,11 +138,29 @@ __pthread_rwlock_unlock:
 	bra	4b
 	 nop
 
+7:
+	mov.l	r4, @-r15
+	mov.l	r6, @-r15
+	mov	r8, r4
+#if MUTEX != 0
+	add	#MUTEX, r4
+#endif
+	mov.l	.Lwake9, r1
+	bsrf	r1
+	 nop
+.Lwake9b:
+
+	mov.l	@r15+, r6
+	bra	8b
+	 mov.l	@r15+, r4
+
 	.align	2
 .Lwait8:	
 	.long	__lll_mutex_lock_wait-.Lwait8b
 .Lwake8:
 	.long	__lll_mutex_unlock_wake-.Lwake8b
+.Lwake9:
+	.long	__lll_mutex_unlock_wake-.Lwake9b
 	.size	__pthread_rwlock_unlock,.-__pthread_rwlock_unlock
 
 	.globl	pthread_rwlock_unlock
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 06d56e04cb..1456292a73 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_rwlock_wrlock.S
@@ -72,7 +72,8 @@ __pthread_rwlock_wrlock:
 	mov	r8, r4
 	add	#WRITERS_WAKEUP, r4
 	mov	#FUTEX_WAIT, r5
-	mov	#0, r6
+	mov.l	@(WRITERS_WAKEUP,r8), r6
+	mov	#0, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
@@ -88,19 +89,16 @@ __pthread_rwlock_wrlock:
 	tst	r2, r2
 	bf	12f
 13:
-	mov.l	@(READERS_QUEUED,r8), r0
+	mov.l	@(WRITERS_QUEUED,r8), r0
 	add	#-1, r0
-	mov.l	r0, @(READERS_QUEUED,r8)
-	mov	#0, r0
 	bra	2b
-	 mov.l	r0, @(WRITERS_WAKEUP,r8)
+	 mov.l	r0, @(WRITERS_QUEUED,r8)
 
 5:
 	mov	#0, r3
-	stc	gbr, r1
+	stc	gbr, r0
 	mov.w	.Ltcboff,r2
-	sub	r2,r1
-	mov.l	@(8,r1),r0
+	sub	r2,r0
 	mov.l	r0, @(WRITER,r8)
 9:
 #if MUTEX == 0
@@ -133,7 +131,6 @@ __pthread_rwlock_wrlock:
 	stc	gbr, r1
 	mov.w	.Ltcboff,r2
 	sub	r2,r1
-	mov.l	@(8,r1),r1
 	cmp/eq	r1, r0
 	bf	3b
 	bra	9b
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
index 90e63ed184..a080e17abe 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S
@@ -51,7 +51,7 @@ __new_sem_post:
 	 mov	#0, r0
 
 1:
-	mov	#EAGAIN, r2
+	mov	#EINVAL, r2
 	mova	.Lgot3, r0
 	mov.l	.Lgot3, r12
 	add	r0, r12
@@ -84,4 +84,4 @@ __new_sem_post:
 	.long	__errno_location@PLT-(.Lerrloc3b+2-.)
 #endif
 	.size	__new_sem_post,.-__new_sem_post
-	.symver	__new_sem_post, sem_post@@GLIBC_2.2
+	versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
index c80839ef30..fc505b4af5 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S
@@ -91,4 +91,4 @@ __new_sem_trywait:
 	.long	__errno_location@PLT-(.Lerrloc1b+2-.)
 #endif
 	.size	__new_sem_trywait,.-__new_sem_trywait
-	.symver	__new_sem_trywait, sem_trywait@@GLIBC_2.2
+	versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1)
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
index f7bca99fc3..49b76c6d8c 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S
@@ -104,4 +104,4 @@ __new_sem_wait:
 	.long	__errno_location@PLT-(.Lerrloc0b+2-.)
 #endif
 	.size	__new_sem_wait,.-__new_sem_wait
-	.symver	__new_sem_wait, sem_wait@@GLIBC_2.2
+	versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)