[Pkg-db-devel] Re: (MIPS|amd64)/gcc-assembly mutexes [#11575]

Thiemo Seufer ica2_ts@csv.ica.uni-stuttgart.de
Tue, 7 Dec 2004 17:02:56 +0100


Thiemo Seufer wrote:
> Clint Adams wrote:
> > > > > > This is a patch for fast mutexes on MIPS & amd64 by Kurt Roeckx against
> > > > 
> > > > Actually, the MIPS portion appears to have a problem.  I'll let you know
> > > > when we work this out.
> > > 
> > > I suggest you talk Thiemo Seufer
> > > <seufer@csv.ica.uni-stuttgart.de> about it.  He already knew
> > > about the patch and changed it for mips.  I've CC'd him.
> > 
> > Thiemo, can you comment on the assembler failure at
> > http://buildd.debian.org/fetch.php?&pkg=db4.3&ver=4.3.21-6&arch=mips&stamp=1102304464&file=log&as=raw
> > ?
> 
> I have a better patch for db4.1 ff, and will post it after I managed
> to get the db4.1 testsuite to do a test run with it. (Currently it
> hangs in the first few tests, I guess caused by tcl version problems.)

The appended patch (for db4.1) is derived from Kurt's one. The handling
of --enable-pthreadsmutexes follows now the usual scheme (but is still
disabled by default). The amd64/mips MUTEX_UNSET defines have now
volatile access.

The MIPS mutex implementation is now less complicated, more performant,
includes a workaround for the R10000 atomicity hardware bug, and works
also reliably with newer compilers.

The same MIPS mutex implementation should also be used in the other
db versions. This isn't immediately release critical, but there are
two problems with the previous implementations:
 - They may fail for some more CPUs besides the buggy R10000, altough
   not for currently supported ones.
 - gcc 4.0 (and probably even 3.4) may cause silently broken code due
   to the way the inline assembler constraints are specified. It will
   still work for gcc 3.3, which is the default compiler for sarge.


Thiemo


diff -urpN db4.1-4.1.25/dbinc/mutex.h db4.1-4.1.25.changed/dbinc/mutex.h
--- db4.1-4.1.25/dbinc/mutex.h	2002-12-19 17:39:08.000000000 +0100
+++ db4.1-4.1.25.changed/dbinc/mutex.h	2004-12-07 03:18:43.000000000 +0100
@@ -463,6 +463,44 @@ typedef unsigned char tsl_t;
 #endif
 
 /*********************************************************************
+ * MIPS/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_MIPS_GCC_ASSEMBLY
+typedef u_int32_t tsl_t;
+
+#ifndef MUTEX_ALIGN
+#define MUTEX_ALIGN sizeof(u_int32_t)
+#endif
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * For gcc/MIPS.  Should return 0 if could not acquire the lock, 1 if
+ * lock was acquired properly.
+ */
+static inline int
+MUTEX_SET(tsl_t *tsl) {
+       register tsl_t *__l = tsl;
+       register tsl_t __r;
+       __asm__ __volatile__(
+               "       .set push           \n"
+               "       .set mips2          \n"
+               "       .set noreorder      \n"
+	        "       .set nomacro        \n"
+               "1:     ll      %0, %1      \n"
+               "       addiu   %0, $0, 1   \n"
+               "       sc      %0, %1      \n"
+               "       beqzl   %0, 1b      \n"
+               "       .set pop              "
+               : "=&r" (__r), "+R" (*__l));
+       return __r;
+}
+
+#define	MUTEX_UNSET(tsl)        (*(volatile tsl_t *)(tsl) = 0)
+#define	MUTEX_INIT(tsl)         MUTEX_UNSET(tsl)
+#endif
+#endif
+
+/*********************************************************************
  * PowerPC/gcc assembly.
  *********************************************************************/
 #if defined(HAVE_MUTEX_PPC_GENERIC_GCC_ASSEMBLY) ||			\
@@ -690,6 +732,31 @@ typedef unsigned char tsl_t;
 #endif
 #endif
 
+/*********************************************************************
+ * amd64/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_X86_64_GCC_ASSEMBLY
+typedef unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * For gcc/amd64, 0 is clear, 1 is set.
+ */
+#define  MUTEX_SET(tsl) ({						\
+	register tsl_t *__l = (tsl);					\
+	int __r;							\
+	asm volatile("mov $1,%%rax; lock; xchgb %1,%%al; xor $1,%%rax"	\
+	    : "=&a" (__r), "=m" (*__l)					\
+	    : "1" (*__l)						\
+	    );								\
+	__r & 1;							\
+})
+
+#define	MUTEX_UNSET(tsl)        (*(volatile tsl_t *)(tsl) = 0)
+#define	MUTEX_INIT(tsl)         MUTEX_UNSET(tsl)
+#endif
+#endif
+
 /*
  * Mutex alignment defaults to one byte.
  *
diff -urpN db4.1-4.1.25/debian/rules db4.1-4.1.25.changed/debian/rules
--- db4.1-4.1.25/debian/rules	2004-12-07 09:52:59.000000000 +0100
+++ db4.1-4.1.25.changed/debian/rules	2004-11-28 06:46:31.000000000 +0100
@@ -32,6 +32,7 @@ CONFIGURE_SWITCHES =    --prefix=/usr \
 			--enable-cxx \
 			--enable-compat185 \
 			--enable-rpc \
+			--enable-pthreadsmutexes \
 			--with-uniquename \
 			--enable-tcl \
 			--with-tcl=/usr/lib/tcl8.4 \
diff -urpN db4.1-4.1.25/dist/aclocal/mutex.ac db4.1-4.1.25.changed/dist/aclocal/mutex.ac
--- db4.1-4.1.25/dist/aclocal/mutex.ac	2002-07-31 21:19:20.000000000 +0200
+++ db4.1-4.1.25.changed/dist/aclocal/mutex.ac	2004-11-27 22:44:39.000000000 +0100
@@ -194,28 +194,31 @@ fi
 # Try with and without the -lpthread library.  If the user specified we use
 # POSIX pthreads mutexes, and we fail to find the full interface, try and
 # configure for just intra-process support.
-if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then
-	AM_PTHREADS_SHARED("POSIX/pthreads")
-fi
-if test "$db_cv_mutex" = no -o \
-    "$db_cv_mutex" = "posix_only" -o "$db_cv_mutex" = "posix_library_only"; then
-	LIBS="$LIBS -lpthread"
-	AM_PTHREADS_SHARED("POSIX/pthreads/library")
-	LIBS="$orig_libs"
-fi
-if test "$db_cv_mutex" = "posix_only"; then
-	AM_PTHREADS_PRIVATE("POSIX/pthreads/private")
-fi
-if test "$db_cv_mutex" = "posix_only" -o \
-    "$db_cv_mutex" = "posix_library_only"; then
-	LIBS="$LIBS -lpthread"
-	AM_PTHREADS_PRIVATE("POSIX/pthreads/library/private")
-	LIBS="$orig_libs"
-fi
-
-if test "$db_cv_mutex" = "posix_only" -o \
-    "$db_cv_mutex" = "posix_library_only"; then
-	AC_MSG_ERROR([unable to find POSIX 1003.1 mutex interfaces])
+if test "$db_cv_pthreadsmutexes" = yes; then
+	if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then
+		AM_PTHREADS_SHARED("POSIX/pthreads")
+	fi
+	if test "$db_cv_mutex" = no -o \
+	    "$db_cv_mutex" = "posix_only" -o \
+	    "$db_cv_mutex" = "posix_library_only"; then
+		LIBS="$LIBS -lpthread"
+		AM_PTHREADS_SHARED("POSIX/pthreads/library")
+		LIBS="$orig_libs"
+	fi
+	if test "$db_cv_mutex" = "posix_only"; then
+		AM_PTHREADS_PRIVATE("POSIX/pthreads/private")
+	fi
+	if test "$db_cv_mutex" = "posix_only" -o \
+	    "$db_cv_mutex" = "posix_library_only"; then
+		LIBS="$LIBS -lpthread"
+		AM_PTHREADS_PRIVATE("POSIX/pthreads/library/private")
+		LIBS="$orig_libs"
+	fi
+
+	if test "$db_cv_mutex" = "posix_only" -o \
+	    "$db_cv_mutex" = "posix_library_only"; then
+		AC_MSG_ERROR([unable to find POSIX 1003.1 mutex interfaces])
+	fi
 fi
 
 # msemaphore: HPPA only
@@ -349,6 +352,17 @@ AC_TRY_COMPILE(,[
 ], [db_cv_mutex="ARM/gcc-assembly"])
 fi
 
+# MIPS/gcc: Linux
+if test "$db_cv_mutex" = no; then
+AC_TRY_COMPILE(,[
+#if defined(__mips__) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+], [db_cv_mutex="MIPS/gcc-assembly"])
+fi
+
 # PaRisc/gcc: HP/UX
 if test "$db_cv_mutex" = no; then
 AC_TRY_COMPILE(,[
@@ -425,7 +439,18 @@ AC_TRY_COMPILE(,[
 ], [db_cv_mutex="S390/gcc-assembly"])
 fi
 
-# ia86/gcc: Linux
+# AMD64/gcc: FreeBSD, NetBSD, BSD/OS, Linux
+if test "$db_cv_mutex" = no; then
+AC_TRY_COMPILE(,[
+#if (defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+], [db_cv_mutex="x86_64/gcc-assembly"])
+fi
+
+# ia64/gcc: Linux
 if test "$db_cv_mutex" = no; then
 AC_TRY_COMPILE(,[
 #if defined(__ia64) && defined(__GNUC__)
@@ -566,10 +591,18 @@ UTS/cc-assembly)	ADDITIONAL_OBJS="$ADDIT
 			AC_DEFINE(HAVE_MUTEX_UTS_CC_ASSEMBLY)
 			AH_TEMPLATE(HAVE_MUTEX_UTS_CC_ASSEMBLY,
 			    [Define to 1 to use the UTS compiler and assembly language mutexes.]);;
+MIPS/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			AC_DEFINE(HAVE_MUTEX_MIPS_GCC_ASSEMBLY)
+			AH_TEMPLATE(HAVE_MUTEX_MIPS_GCC_ASSEMBLY,
+			    [Define to 1 to use the GCC compiler and MIPS assembly language mutexes.]);;
 x86/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
 			AC_DEFINE(HAVE_MUTEX_X86_GCC_ASSEMBLY)
 			AH_TEMPLATE(HAVE_MUTEX_X86_GCC_ASSEMBLY,
 			    [Define to 1 to use the GCC compiler and x86 assembly language mutexes.]);;
+x86_64/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			AC_DEFINE(HAVE_MUTEX_X86_64_GCC_ASSEMBLY)
+			AH_TEMPLATE(HAVE_MUTEX_X86_64_GCC_ASSEMBLY,
+			    [Define to 1 to use the GCC compiler and AMD64 assembly language mutexes.]);;
 UNIX/fcntl)		AC_MSG_WARN(
 			    [NO FAST MUTEXES FOUND FOR THIS COMPILER/ARCHITECTURE.])
 			ADDITIONAL_OBJS="mut_fcntl${o} $ADDITIONAL_OBJS"
diff -urpN db4.1-4.1.25/dist/aclocal/options.ac db4.1-4.1.25.changed/dist/aclocal/options.ac
--- db4.1-4.1.25/dist/aclocal/options.ac	2002-06-26 20:52:00.000000000 +0200
+++ db4.1-4.1.25.changed/dist/aclocal/options.ac	2004-11-28 00:55:45.000000000 +0100
@@ -67,6 +67,13 @@ AC_ARG_ENABLE(java,
 	[db_cv_java="$enable_java"], [db_cv_java="no"])
 AC_MSG_RESULT($db_cv_java)
 
+AC_MSG_CHECKING(if --enable-pthreadsmutexes option specified)
+AC_ARG_ENABLE(pthreadsmutexes,
+	AC_HELP_STRING([--enable-pthreadsmutexes],
+		       [Use POSIX pthreads mutexes.]),
+	[db_cv_pthreadsmutexes="$enable_pthreadsmutexes"], [db_cv_pthreadsmutexes="no"])
+AC_MSG_RESULT($db_cv_pthreadsmutexes)
+
 AC_MSG_CHECKING(if --enable-posixmutexes option specified)
 AC_ARG_ENABLE(posixmutexes,
 	[AC_HELP_STRING([--enable-posixmutexes],
diff -urpN db4.1-4.1.25/dist/config.hin db4.1-4.1.25.changed/dist/config.hin
--- db4.1-4.1.25/dist/config.hin	2002-09-14 00:15:27.000000000 +0200
+++ db4.1-4.1.25.changed/dist/config.hin	2004-11-28 00:56:20.000000000 +0100
@@ -107,6 +107,9 @@
 /* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */
 #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY
 
+/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */
+#undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY
+
 /* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */
 #undef HAVE_MUTEX_MSEM_INIT
 
@@ -168,6 +171,9 @@
 /* Define to 1 to use Windows mutexes. */
 #undef HAVE_MUTEX_WIN32
 
+/* Define to 1 to use the GCC compiler and AMD64 assembly language mutexes. */
+#undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY
+
 /* Define to 1 to use the GCC compiler and x86 assembly language mutexes. */
 #undef HAVE_MUTEX_X86_GCC_ASSEMBLY