about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S225
1 files changed, 159 insertions, 66 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
index 115c5292dd..936a4e3868 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S
@@ -28,111 +28,204 @@
 #define FUTEX_WAKE		1
 
 
-	.globl	__lll_lock_wait
-	.type	__lll_lock_wait,@function
-	.hidden	__lll_lock_wait
+	.globl	__lll_mutex_lock_wait
+	.type	__lll_mutex_lock_wait,@function
+	.hidden	__lll_mutex_lock_wait
 	.align	5
-__lll_lock_wait:
+__lll_mutex_lock_wait:
+	mov.l	r8, @-r15
 	mov	r4, r6
-	mov	r5, r4
+	mov	r5, r8
 	mov	#0, r7		/* No timeout.  */
 	mov	#FUTEX_WAIT, r5
-2:
-	add	#-1, r6		/* account for the preceeded xadd.  */
+1:
+	mov	#2, r4
+	cmp/eq	r4, r6
+	bt	3f
+
+	mov	#1, r3
+	CMPXCHG (r3, @r8, r4, r2)
+	tst	r2, r2
+	bt	2f
+
+3:
+	mov	r8, r4
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
-	mov	#-1, r3
-	XADD (r3, @r4, r2)
-	tst	r3, r3
-	bf/s	2b
-	 mov	r2, r6
+2:
+	mov	#0, r3
+	mov	#2, r4
+	CMPXCHG (r3, @r8, r4, r2)
+	bf	1b
 
-	mov	#-1, r1
-	mov.l	r1, @r4
-	rts
+	mov.l	@r15+, r8
+	ret
 	 mov	r2, r0
-	.size	__lll_lock_wait,.-__lll_lock_wait
+	.size	__lll_mutex_lock_wait,.-__lll_mutex_lock_wait
 
 
 #ifdef NOT_IN_libc
-	.globl	lll_unlock_wake_cb
-	.type	lll_unlock_wake_cb,@function
-	.hidden	lll_unlock_wake_cb
+	.globl	__lll_mutex_timedlock_wait
+	.type	__lll_mutex_timedlock_wait,@function
+	.hidden	__lll_mutex_timedlock_wait
 	.align	5
-lll_unlock_wake_cb:
+__lll_mutex_timedlock_wait:
+	/* Check for a valid timeout value.  */
+	mov.l	@(4,r6), r1
+	mov.l	.L1g, r0
+	cmp/hs	r0, r1
+	bt	3f
+
+	mov.l	r10, @-r15
+	mov.l	r9, @-r15
+	mov.l	r8, @-r15
+	mov	r4, r10
+	mov	r6, r9
+	mov	r5, r8
+
+	/* Stack frame for the timespec and timeval structs.  */
+	add	#-8, r15
 
-	.align	2
-	mova	1f, r0
-	mov	r15, r1
-	mov	#-6, r15
-0:
-	mov.l	@r4, r2
-	add	#1, r2
-	mov.l	r2, @r4
 1:
-	mov	r1, r15
-	cmp/pl	r2
-	bf	2f
+	/* Get current time.  */
+	mov	r15, r4
+	mov	#0, r5
+	mov	#SYS_gettimeofday, r3
+	trapa	#0x12
+	SYSCALL_INST_PAD
+
+	/* Compute relative timeout.  */
+	mov.l	@(4,r15), r0
+	mov.w	.L1k, r1
+	dmulu.l	r0, r1		/* Micro seconds to nano seconds.  */
+	mov.l	@r9, r2
+	mov.l	@(4,r9), r3
+	mov.l	@r15, r0
+	sts	macl, r1
+	sub	r0, r2
+	clrt
+	subc	r1, r3
+	bf	4f
+	mov.l	.L1g, r1
+	add	r1, r3
+	add	#-1, r2
+4:
+	cmp/pz	r2
+	bf	5f		/* Time is already up.  */
+
+	mov.l	r2, @r15	/* Store relative timeout.  */
+	mov.l	r3, @(4,r15)
+
+	mov	#1, r3
+	mov	#2, r4
+	CMPXCHG (r3, @r8, r4, r2)
+	bt	8f
+
+	mov	r8, r4
+	mov	#FUTEX_WAIT, r5
+	mov	r10, r6
+	mov	r15, r7
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x14
+	SYSCALL_INST_PAD
+	mov	r0, r4
+
+8:	
+	mov	#0, r3
+	mov	#2, r4
+	CMPXCHG (r3, @r8, r4, r2)
+	bf	7f
+
+6:
+	add	#8, r15
+	mov.l	@r15+, r8
+	mov.l	@r15+, r9
 	rts
+	 mov.l	@r15+, r10
+7:
+	/* Check whether the time expired.  */
+	mov	#-ETIMEDOUT, r1
+	cmp/eq	r4, r1
+	bt	5f
+	bra	1b
 	 nop
-	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
+3:
+	rts
+	 mov	#EINVAL, r0
+5:
+	bra	6b
+	 mov	#ETIMEDOUT, r0
+
+.L1k:
+	.word	1000
+	.align	2
+.L1g:
+	.long	1000000000
+
+	.size	__lll_mutex_timedlock_wait,.-__lll_mutex_timedlock_wait
 #endif
 
 
-	.globl	__lll_unlock_wake
-	.type	__lll_unlock_wake,@function
-	.hidden	__lll_unlock_wake
-__lll_unlock_wake:
-2:
+#ifdef NOT_IN_libc
+	.globl	lll_unlock_wake_cb
+	.type	lll_unlock_wake_cb,@function
+	.hidden	lll_unlock_wake_cb
+	.align	5
+lll_unlock_wake_cb:
+	DEC	(@r4, r2)
+	tst	r2, r2
+	bt	1f
+
 	mov	#FUTEX_WAKE, r5
 	mov	#1, r6		/* Wake one thread.  */
 	mov	#0, r7
-	mov.l	r6, @r4		/* Stores 1.  */
+	mov.l	r7, @r4		/* Stores 0.  */
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
+
+1:	
 	rts
 	 nop
-	.size	__lll_unlock_wake,.-__lll_unlock_wake
+	.size	lll_unlock_wake_cb,.-lll_unlock_wake_cb
+#endif
 
 
-#ifdef NOT_IN_libc
-	.globl	__lll_wait_tid
-	.type	__lll_wait_tid,@function
-	.hidden	__lll_wait_tid
-__lll_wait_tid:
-	mov.l	@r4, r6
-1:
-	mov	#FUTEX_WAIT, r5
+	.globl	__lll_mutex_unlock_wake
+	.type	__lll_mutex_unlock_wake,@function
+	.hidden	__lll_mutex_unlock_wake
+	.align	5
+__lll_mutex_unlock_wake:
+	mov	#FUTEX_WAKE, r5
+	mov	#1, r6		/* Wake one thread.  */
 	mov	#0, r7
+	mov.l	r7, @r4		/* Stores 0.  */
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
-
-	mov	r0, r1
-
-	mov.l	@r4, r0
-	tst	r0, r0
-	bf/s	1b
-	 mov	r0, r6
 	rts
 	 nop
-	.size	__lll_wait_tid,.-__lll_wait_tid
+	.size	__lll_mutex_unlock_wake,.-__lll_mutex_unlock_wake
 
 
+#ifdef NOT_IN_libc
 	.globl	__lll_timedwait_tid
 	.type	__lll_timedwait_tid,@function
 	.hidden	__lll_timedwait_tid
+	.align	5
 __lll_timedwait_tid:
 	mov.l	r9, @-r15
 	mov.l	r8, @-r15
 	mov	r4, r8
 	mov	r5, r9
+
+	/* Stack frame for the timespec and timeval structs.  */
 	add	#-8, r15
 
 2:
@@ -145,8 +238,8 @@ __lll_timedwait_tid:
 
 	/* Compute relative timeout.  */
 	mov.l	@(4,r15), r0
-	mov.w	.L1k, r1
-	dmulu.l	r0, r1		/* Milli seconds to nano seconds.  */
+	mov.w	.L1k2, r1
+	dmulu.l	r0, r1		/* Micro seconds to nano seconds.  */
 	mov.l	@r9, r2
 	mov.l	@(4,r9), r3
 	mov.l	@r15, r0
@@ -155,7 +248,7 @@ __lll_timedwait_tid:
 	clrt
 	subc	r1, r3
 	bf	5f
-	mov.l	.L1g, r1
+	mov.l	.L1g2, r1
 	add	r1, r3
 	add	#-1, r2
 5:
@@ -165,20 +258,21 @@ __lll_timedwait_tid:
 	mov.l	r2, @r15	/* Store relative timeout.  */
 	mov.l	r3, @(4,r15)
 
-	mov.l	@r8, r6
-	tst	r6, r6
+	mov.l	@r8, r2
+	tst	r2, r2
 	bt	4f
 
 	mov	r8, r4
 	mov	#FUTEX_WAIT, r5
+	mov	r2, r6
 	mov	r15, r7
 	mov	#SYS_futex, r3
 	extu.b	r3, r3
 	trapa	#0x14
 	SYSCALL_INST_PAD
 
-	mov.l	@r8, r0
-	tst	r0, r0
+	mov.l	@r8, r2
+	tst	r2, r2
 	bf	1f
 4:
 	mov	#0, r0
@@ -187,8 +281,8 @@ __lll_timedwait_tid:
 	mov.l	@r15+, r8
 	rts
 	 mov.l	@r15+, r9
-
 1:
+	/* Check whether the time expired.  */
 	mov	#-ETIMEDOUT, r1
 	cmp/eq	r0, r1
 	bf	2b
@@ -196,11 +290,10 @@ __lll_timedwait_tid:
 	bra	3b
 	 mov	#ETIMEDOUT, r0
 
-.L1k:
+.L1k2:
 	.word	1000
 	.align	2
-.L1g:
+.L1g2:
 	.long	1000000000
-
 	.size	__lll_timedwait_tid,.-__lll_timedwait_tid
 #endif