about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-03-29 01:24:20 +0000
committerUlrich Drepper <drepper@redhat.com>2003-03-29 01:24:20 +0000
commitdd731d53dcdbb24cd2a3f299a2ba4362505d3f55 (patch)
tree9db2cc09616d8073cc8c2888036e01cc60970d5b /nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S
parent10e717a20778341a2e8c7d11e3cb1cc90e943602 (diff)
downloadglibc-dd731d53dcdbb24cd2a3f299a2ba4362505d3f55.tar.gz
glibc-dd731d53dcdbb24cd2a3f299a2ba4362505d3f55.tar.xz
glibc-dd731d53dcdbb24cd2a3f299a2ba4362505d3f55.zip
Update.
2003-03-28  Kaz Kojima  <kkojima@rr.iij4u.or.jp>

	* sysdeps/sh/bits/atomic.h (__arch_compare_and_exchange_val_8_acq):
	Return old value. Make asm output reg constraint earlyclobber.
	Renamed from...
	(__arch_compare_and_exchange_8_acq): ... this.
	(__arch_compare_and_exchange_val_16_acq):
	Return old value. Make asm output reg constraint earlyclobber.
	Renamed from...
	(__arch_compare_and_exchange_16_acq): ... this.
	(__arch_compare_and_exchange_val_32_acq):
	Return old value. Make asm output reg constraint earlyclobber.
	Renamed from...
	(__arch_compare_and_exchange_32_acq): ... this.
	(__arch_compare_and_exchange_val_64_acq):
	Renamed from...
	(__arch_compare_and_exchange_64_acq): ... this.
	(atomic_exchange_and_add): Use local variables and
	__arch_compare_and_exchange_val_64_acq.
	(atomic_add): Likewise.
	(atomic_add_negative, atomic_add_zero): Use local variables.

	* Makefile: Remove libmd5crypt goal.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_wait.S102
1 files changed, 82 insertions, 20 deletions
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)