about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-02-17 15:37:51 +0000
committerUlrich Drepper <drepper@redhat.com>2006-02-17 15:37:51 +0000
commita7245bf5271d49ed6d13d242801e50ae9911d072 (patch)
tree38465c20b0c4dc56590f73282db0150c7fde0138
parent49bfc1fe3d7a2d4ad5ef670590441f202bf4f51c (diff)
downloadglibc-cvs/fedora-glibc-20060217T1609.tar.gz
glibc-cvs/fedora-glibc-20060217T1609.tar.xz
glibc-cvs/fedora-glibc-20060217T1609.zip
* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Add lll_robust_mutex_* cvs/fedora-glibc-20060217T1609
	definitions.
	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: New file.
-rw-r--r--nptl/ChangeLog6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h111
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S224
3 files changed, 341 insertions, 0 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index f2ca4307f1..aa206ebd2f 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,9 @@
+2006-02-17  Kaz Kojima  <kkojima@rr.iij4u.or.jp>
+
+	* sysdeps/unix/sysv/linux/sh/lowlevellock.h: Add lll_robust_mutex_*
+	definitions.
+	* sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S: New file.
+
 2006-02-17  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
index e3e3777f44..92f93cd5f5 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
@@ -62,6 +62,28 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	: "r0", "r1", "r2", "t", "memory"); \
      __result; })
 
+#define lll_robust_mutex_trylock(futex, id)	\
+  ({ unsigned char __result; \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%1,r2\n\
+	cmp/eq r2,%3\n\
+	bf 1f\n\
+	mov.l %2,@%1\n\
+     1: mov r1,r15\n\
+	mov #-1,%0\n\
+	negc %0,%0"\
+	: "=r" (__result) \
+	: "r" (&(futex)), \
+	  "r" (id), \
+	  "r" (LLL_MUTEX_LOCK_INITIALIZER) \
+	: "r0", "r1", "r2", "t", "memory"); \
+     __result; })
+
 #define lll_mutex_cond_trylock(futex) \
   ({ unsigned char __result; \
      __asm __volatile ("\
@@ -102,6 +124,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_lock(futex, id)		    \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+      0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+      1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+     if (__result) \
+       __result = __lll_robust_mutex_lock_wait (__result, __futex); \
+     __result; })
+
 /* Special version of lll_mutex_lock which causes the unlock function to
    always wakeup waiters.  */
 #define lll_mutex_cond_lock(futex) \
@@ -122,6 +163,25 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_lock_wait (__result, __futex); })
 
+#define lll_robust_mutex_cond_lock(futex, id)	    \
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+     1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id | FUTEX_WAITERS), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+      if (__result) \
+	__result = __lll_robust_mutex_lock_wait (__result, __futex); \
+      __result; })
+
 #define lll_mutex_timedlock(futex, timeout) \
   ({ int __result, val, *__futex = &(futex); \
      __asm __volatile ("\
@@ -141,6 +201,26 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
       __result = __lll_mutex_timedlock_wait (__result, __futex, timeout); \
     __result; })
 
+#define lll_robust_mutex_timedlock(futex, timeout, id)	\
+  ({ int __result, val, *__futex = &(futex); \
+     __asm __volatile ("\
+	.align 2\n\
+	mova 1f,r0\n\
+	nop\n\
+	mov r15,r1\n\
+	mov #-8,r15\n\
+     0: mov.l @%2,%0\n\
+	tst %0,%0\n\
+	bf 1f\n\
+	mov.l %1,@%2\n\
+     1: mov r1,r15"\
+	: "=&r" (__result) : "r" (id), "r" (__futex) \
+	: "r0", "r1", "t", "memory"); \
+    if (__result) \
+      __result = __lll_robust_mutex_timedlock_wait (__result, __futex, \
+						    timeout);	       \
+    __result; })
+
 #define lll_mutex_unlock(futex) \
   (void) ({ int __result, *__futex = &(futex); \
 	    __asm __volatile ("\
@@ -157,6 +237,37 @@ extern int __lll_mutex_unlock_wake (int *__futex) attribute_hidden;
 	    if (__result) \
 	      __lll_mutex_unlock_wake (__futex); })
 
+#define lll_robust_mutex_unlock(futex) \
+  (void) ({ int __result, *__futex = &(futex); \
+	    __asm __volatile ("\
+		.align 2\n\
+		mova 1f,r0\n\
+		mov r15,r1\n\
+		mov #-6,r15\n\
+	     0: mov.l @%1,%0\n\
+		and %2,%0\n\
+		mov.l %0,@%1\n\
+	     1: mov r1,r15"\
+		: "=&r" (__result) : "r" (__futex), "r" (FUTEX_TID_MASK) \
+		: "r0", "r1", "memory");	\
+	    if (__result) \
+	      __lll_mutex_unlock_wake (__futex); })
+
+#define lll_robust_mutex_dead(futex) \
+  (void) ({ int __ignore, *__futex = &(futex); \
+	    __asm __volatile ("\
+		.align 2\n\
+		mova 1f,r0\n\
+		mov r15,r1\n\
+		mov #-6,r15\n\
+	     0: mov.l @%1,%0\n\
+		or %2,%0\n\
+		mov.l %0,@%1\n\
+	     1: mov r1,r15"\
+		: "=&r" (__ignore) : "r" (__futex), "r" (FUTEX_OWNER_DIED) \
+		: "r0", "r1", "memory");	\
+	    lll_futex_wake (__futex, 1); })
+
 #define lll_mutex_islocked(futex) \
   (futex != 0)
 
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
new file mode 100644
index 0000000000..c57d3cff18
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/sh/lowlevelrobustlock.S
@@ -0,0 +1,224 @@
+/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <pthread-errnos.h>
+#include <lowlevelrobustlock.h>
+#include "lowlevel-atomic.h"
+
+	.text
+
+#define SYS_gettimeofday	__NR_gettimeofday
+#define SYS_futex		240
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+#define FUTEX_WAITERS		0x80000000
+#define FUTEX_OWNER_DIED	0x40000000
+
+
+	.globl	__lll_robust_mutex_lock_wait
+	.type	__lll_robust_mutex_lock_wait,@function
+	.hidden	__lll_robust_mutex_lock_wait
+	.align	5
+	cfi_startproc
+__lll_robust_mutex_lock_wait:
+	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
+	mov	r5, r8
+	mov	#0, r7		/* No timeout.  */
+	mov	#FUTEX_WAIT, r5
+
+4:
+	mov	r4, r6
+	mov.l	.L_FUTEX_WAITERS, r0
+	or	r0, r6
+	shlr	r0		/* r0 = FUTEX_OWNER_DIED */
+	tst	r0, r4
+	bf/s	3f
+	 cmp/eq	r4, r6
+	bt	1f
+
+	CMPXCHG (r4, @r8, r6, r2)
+	bf	2f
+
+1:
+	mov	r8, r4
+	mov	#SYS_futex, r3
+	extu.b	r3, r3
+	trapa	#0x14
+	SYSCALL_INST_PAD
+
+	mov.l	@r8, r2
+
+2:
+	tst	r2, r2
+	bf/s	4b
+	 mov	r2, r4
+
+	stc	gbr, r1
+	mov.w	.Ltidoff, r2
+	add	r2, r1
+	mov.l	@r1, r6
+	mov	#0, r3
+	CMPXCHG (r3, @r8, r6, r4)
+	bf	4b
+	mov	#0, r4
+
+3:
+	mov.l	@r15+, r8
+	ret
+	 mov	r4, r0
+	cfi_endproc
+	.align	2
+.L_FUTEX_WAITERS:
+	.long	FUTEX_WAITERS
+.Ltidoff:
+	.word	TID - TLS_PRE_TCB_SIZE
+	.size	__lll_robust_mutex_lock_wait,.-__lll_robust_mutex_lock_wait
+
+
+	.globl	__lll_robust_mutex_timedlock_wait
+	.type	__lll_robust_mutex_timedlock_wait,@function
+	.hidden	__lll_robust_mutex_timedlock_wait
+	.align	5
+	cfi_startproc
+__lll_robust_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
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r10, 0)
+	mov.l	r9, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r9, 0)
+	mov.l	r8, @-r15
+	cfi_adjust_cfa_offset(4)
+	cfi_rel_offset (r8, 0)
+	mov	r4, r10
+	mov	r6, r9
+	mov	r5, r8
+
+	/* Stack frame for the timespec and timeval structs.  */
+	add	#-8, r15
+	cfi_adjust_cfa_offset(8)
+
+1:
+	/* 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	8f		/* Time is already up.  */
+
+	mov.l	r2, @r15	/* Store relative timeout.  */
+	mov.l	r3, @(4,r15)
+
+	mov	r10, r6
+	mov.l	.L_FUTEX_WAITERS2, r0
+	or	r0, r6
+	shlr	r0		/* r0 = FUTEX_OWNER_DIED */
+	tst	r0, r4
+	bf/s	6f
+	 cmp/eq	r4, r6
+	bt	2f
+
+	CMPXCHG (r4, @r8, r6, r2)
+	bf/s	5f
+	 mov	#0, r5
+
+2:
+	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, r5
+
+	mov.l	@r8, r2
+
+5:
+	tst	r2, r2
+	bf/s	7f
+	 mov	r2, r10
+
+	stc	gbr, r1
+	mov.w	.Ltidoff2, r2
+	add	r2, r1
+	mov.l	@r1, r4
+	mov	#0, r3
+	CMPXCHG (r3, @r8, r4, r10)
+	bf	7f
+	mov	#0, r0
+
+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	r5, r1
+	bf	1b
+
+8:
+	bra	6b
+	 mov	#ETIMEDOUT, r0
+3:
+	rts
+	 mov	#EINVAL, r0
+	cfi_endproc
+	.align	2
+.L_FUTEX_WAITERS2:
+	.long	FUTEX_WAITERS
+.L1g:
+	.long	1000000000
+.Ltidoff2:
+	.word	TID - TLS_PRE_TCB_SIZE
+.L1k:
+	.word	1000
+	.size	__lll_robust_mutex_timedlock_wait,.-__lll_robust_mutex_timedlock_wait