Bug#63188: [PATCH] db: fix and enable spinlocks (and thus DB_THREAD) on Alpha
Package: libdb2
Version: 2.4.14-2.7.7.1.0
Severity: important
Hi,
DB *has* an implementation of spinlocks for Alpha (needed for thread
support, which is used by openldap - slapd will not work without
this!), but it is old, doesn't compile, and isn't actually turned on
in the build (it lives in mutex/ARCHIVE).
Here's one that is new, does compile, and is turned on. Please
forward it to the upstream authors if necessary.
I've set this to important because, like I said, openldapd won't work
(or won't work correctly) without it. I've Cc:'ed to debian-alpha for
verification, so you might want to await comment from there as my
assembly programming skills are still somewhat shaky...
diff -urN --exclude=tags --exclude=configure --exclude=config.h.in db-2.4.14/dist/acconfig.h db-2.4.14-fixed/dist/acconfig.h
--- db-2.4.14/dist/acconfig.h Thu Apr 27 10:07:06 2000
+++ db-2.4.14-fixed/dist/acconfig.h Thu Apr 27 10:00:39 2000
@@ -38,6 +38,9 @@
/* Define if you want to use x86/gcc assembly spinlocks. */
#undef HAVE_ASSEM_X86_GCC
+/* Define if you want to use alpha/gcc assembly spinlocks. */
+#undef HAVE_ASSEM_ALPHA_GCC
+
/* Define if you have the AIX _check_lock spinlocks. */
#undef HAVE_FUNC_AIX
diff -urN --exclude=tags --exclude=configure --exclude=config.h.in db-2.4.14/dist/config.hin db-2.4.14-fixed/dist/config.hin
--- db-2.4.14/dist/config.hin Thu Apr 27 10:07:06 2000
+++ db-2.4.14-fixed/dist/config.hin Thu Apr 27 10:00:39 2000
@@ -64,6 +64,9 @@
/* Define if you want to use x86/gcc assembly spinlocks. */
#undef HAVE_ASSEM_X86_GCC
+/* Define if you want to use alpha/gcc assembly spinlocks. */
+#undef HAVE_ASSEM_ALPHA_GCC
+
/* Define if you have the AIX _check_lock spinlocks. */
#undef HAVE_FUNC_AIX
diff -urN --exclude=tags --exclude=configure --exclude=config.h.in db-2.4.14/dist/configure.in db-2.4.14-fixed/dist/configure.in
--- db-2.4.14/dist/configure.in Thu Apr 27 10:07:06 2000
+++ db-2.4.14-fixed/dist/configure.in Thu Apr 27 10:00:39 2000
@@ -384,6 +384,17 @@
exit(1);}], [db_cv_spinlocks=x86/gcc])
fi
+dnl alpha/gcc: BSD/OS, FreeBSD, NetBSD, Linux
+if test "$db_cv_spinlocks" = no; then
+AC_TRY_RUN([main(){
+#if defined(__alpha__)
+#if defined(__GNUC__)
+exit(0);
+#endif
+#endif
+exit(1);}], [db_cv_spinlocks=alpha/gcc])
+fi
+
dnl: uts/cc: UTS
if test "$db_cv_spinlocks" = no; then
AC_TRY_RUN([main(){
@@ -477,6 +488,10 @@
AC_DEFINE(HAVE_ASSEM_X86_GCC)
mutex_align="1"
spin_line1="typedef unsigned char tsl_t;";;
+alpha/gcc)
+ AC_DEFINE(HAVE_ASSEM_ALPHA_GCC)
+ mutex_align="16"
+ spin_line1="typedef unsigned long tsl_t;";;
*)
mutex_align="1";;
esac
diff -urN --exclude=tags --exclude=configure --exclude=config.h.in db-2.4.14/mutex/alpha.gcc db-2.4.14-fixed/mutex/alpha.gcc
--- db-2.4.14/mutex/alpha.gcc Wed Dec 31 19:00:00 1969
+++ db-2.4.14-fixed/mutex/alpha.gcc Thu Apr 27 10:15:06 2000
@@ -0,0 +1,46 @@
+ /* Alpha inline assembly locking primitives, by David Huggins-Daines
+ <dhd@linuxcare.com>.
+
+ Note: we must align the lock to 16 bytes, because that is the
+ minimum granularity of the lock_flag. It is theoretically possible
+ for the locked range to be much, much larger than this (from
+ a cache line up to an entire page!) but we should be OK.
+
+ The 'mb' instructions guarantee that all access to the structure
+ protected by this lock is done between the acquisition and release
+ of the lock.
+
+ The spaghetti mess of branches is an attempt to not break branch
+ prediction, as recommended by the Architecture Reference Manual.
+ If we knew the extent of the protected section we could do it more
+ optimally. The kernel solves this by moving the failure cases to
+ a separate ELF section, but I don't know if that will work here. */
+
+ #define TSL_SET(tsl) ({ \
+ register tsl_t *__l = (tsl); \
+ unsigned long __r = 0; \
+ asm volatile(" \n\
+ 0: #$start: \n\
+ ldq_l %0,%3 # ldq_l __r,__l \n\
+ blbs %2,3f # blbs __r,$fail \n\
+ bis $31,1,%0 # mov 1,__r \n\
+ stq_c %2,%1 # stq_c __r,__l \n\
+ beq %2,2f # beq __r,$again \n\
+ 1: #$success: \n\
+ mb # mb \n\
+ br $31,4f # br $done \n\
+ 2: #$again: \n\
+ br $31,0b # br $start \n\
+ 3: #$fail: \n\
+ bis $31,$31,%0 # mov 0,__r \n\
+ 4: #$done: \n\
+ " : "=r" (__r), "=m" (*__l) \
+ : "0" (__r), "1" (*__l) : "memory"); \
+ __r; })
+
+ #define TSL_UNSET(tsl) ({ \
+ asm volatile(" \n\
+ mb \n\
+ stq $31,%0" \
+ : "=m" (*(tsl)) :: "memory");})
+ #define TSL_INIT(tsl) TSL_UNSET(tsl)
diff -urN --exclude=tags --exclude=configure --exclude=config.h.in db-2.4.14/mutex/mutex.c db-2.4.14-fixed/mutex/mutex.c
--- db-2.4.14/mutex/mutex.c Thu Apr 27 10:07:06 2000
+++ db-2.4.14-fixed/mutex/mutex.c Thu Apr 27 10:00:39 2000
@@ -110,6 +110,10 @@
#include "x86.gcc"
#endif
+#ifdef HAVE_ASSEM_ALPHA_GCC
+#include "alpha.gcc"
+#endif
+
#ifdef WIN16
/* Win16 spinlocks are simple because we cannot possibly be preempted. */
#define TSL_INIT(tsl)
--
David Huggins-Daines, GNU/Linux Consultant, Linuxcare, Inc.
613.223.0225 mobile
dhd@linuxcare.com, http://www.linuxcare.com/
Linuxcare. Support for the revolution.
Reply to: