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

Thiemo Seufer ica2_ts@csv.ica.uni-stuttgart.de
Wed, 8 Dec 2004 09:36:25 +0100


Clint Adams wrote:
> > 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.
> 
> Okay, I've committed the new mips and amd64 mutex implementations to the
> db4.3 repository, as well as the "ia86" -> "ia64" fix.  I'll upload
> 4.3.21-7 as soon as it's done building.

That's bad news for me, since I managed to botch the mips assembly
part of the patch with a really stupid last-minute change. The old
version builds but fails to work as mutex.

The updated version is appended, the MIPS inline assembly is the only
relevant thing changed. I built both 4.1 amd 4.3 with it and checked
with the respective testsuites.


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,46 @@ 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"
+               "       bne     %0, $0, 1f  \n"
+               "        xori   %0, %0, 1   \n"
+               "       sc      %0, %1      \n"
+               "       beql    %0, $0, 1b  \n"
+               "        xori   %0, 1       \n"
+               "1:     .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/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],