]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
provided __asm version of assembly code for atomic atomic operations
authorTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 16 Jun 2005 21:58:00 +0000 (21:58 +0000)
committerTatuya JINMEI 神明達哉 <jinmei@isc.org>
Thu, 16 Jun 2005 21:58:00 +0000 (21:58 +0000)
for better compatibility.

(this is a temporary resolution so that this one won't block other tests.
we'll revisit this change when we figure out performance implication of
the __asm version.)

configure.in
lib/isc/alpha/include/isc/atomic.h
lib/isc/include/isc/platform.h.in
lib/isc/sparc64/include/isc/atomic.h
lib/isc/x86_32/include/isc/atomic.h

index f3992b188107853ee41df706272f49d147b1e0f8..16428beed9f636b780f1e40b73820eaa346db7a3 100644 (file)
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
 esyscmd([sed "s/^/# /" COPYRIGHT])dnl
 AC_DIVERT_POP()dnl
 
-AC_REVISION($Revision: 1.378 $)
+AC_REVISION($Revision: 1.379 $)
 
 AC_INIT(lib/dns/name.c)
 AC_PREREQ(2.13)
@@ -1867,7 +1867,6 @@ if test "$use_atomic" = "yes"; then
        AC_MSG_CHECKING([architecture type for atomic operations])
        case "$host" in
        [i[3456]86-*]|x86_64-*)
-               # XXX: also need to check portability of the "asm" keyword?
                # XXX: some old x86 architectures actualy do not support
                #      (some of) these operations.  Do we need stricter checks?
                # Note: We currently use the same code for both the x86_32 and
@@ -1879,15 +1878,6 @@ if test "$use_atomic" = "yes"; then
        alpha*-*)
                have_atomic=yes
                arch=alpha
-               if test "X$GCC" != "Xyes"; then
-                       case "$host" in
-                       *-dec-osf*)
-                       # Tru64 compiler has its own syntax for inline
-                       # assembly.
-                       ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1"
-                       ;;
-                       esac
-               fi
        ;;
        *)
                have_atomic=no
@@ -1897,6 +1887,52 @@ if test "$use_atomic" = "yes"; then
        AC_MSG_RESULT($arch)
 fi
 
+if test "$have_atomic" = "yes"; then
+       AC_MSG_CHECKING([compiler support for inline assembly code])
+
+       compiler=generic
+       # Check whehter the compiler supports the assembly syntax we provide.
+       if test "X$GCC" = "Xyes"; then
+               # GCC's ASM extension always works
+               compiler=gcc
+       else
+               case "$host" in
+               alpha*-dec-osf*)
+                       # Tru64 compiler has its own syntax for inline 
+                       # assembly.
+                       AC_TRY_COMPILE(, [
+#ifndef __DECC
+#error "unexpected compiler"
+#endif
+                               return (0);],
+                               [compiler=osf],)
+               ;;
+               esac
+       fi
+       case "$compiler" in
+       gcc)
+               ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1"
+               ;;
+       osf)
+               ISC_PLATFORM_USEOSFASM="#define ISC_PLATFORM_USEOSFASM 1"
+               ;;
+       *)
+               # See if the generic __asm function works.  If not,
+               # we need to disable the atomic operations.
+               AC_TRY_LINK(, [
+                                       __asm("nop")
+                               ],
+               [compiler="standard"
+               ISC_PLATFORM_USESTDASM="#define ISC_PLATFORM_USESTDASM 1"],
+               [compiler="not supported (atomic operations disabled)"
+               have_atomic=no
+               arch=noatomic ]);
+               ;;
+       esac
+
+       AC_MSG_RESULT($compiler)
+fi
+
 if test "$have_atomic" = "yes"; then
        ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1"
        ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1"
@@ -1910,7 +1946,10 @@ fi
 AC_SUBST(ISC_PLATFORM_HAVEXADD)
 AC_SUBST(ISC_PLATFORM_HAVECMPXCHG)
 AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE)
+
+AC_SUBST(ISC_PLATFORM_USEGCCASM)
 AC_SUBST(ISC_PLATFORM_USEOSFASM)
+AC_SUBST(ISC_PLATFORM_USESTDASM)
 
 ISC_ARCH_DIR=$arch
 AC_SUBST(ISC_ARCH_DIR)
index 83fe91d08b8d4f9f82af82e9ddd2176ac5e7bd73..2eb4a1715d7e31f4da5a03e57fb7fb8772f7c469 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: atomic.h,v 1.2 2005/06/04 05:32:48 jinmei Exp $ */
+/* $Id: atomic.h,v 1.3 2005/06/16 21:57:59 jinmei Exp $ */
 
 /*
  * This code was written based on FreeBSD's kernel source whose copyright
@@ -107,7 +107,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
                   "2:",
                   p, cmpval, val));
 }
-#else  /* ISC_PLATFORM_USEOSFASM */
+#elif defined (ISC_PLATFORM_USEGCCASM)
 static inline isc_int32_t 
 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
        isc_int32_t temp, prev;
@@ -161,6 +161,10 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
 
        return (prev);
 }
-#endif /* ISC_PLATFORM_USEOSFASM */
+#else
+
+#error "unsupported compiler.  disable atomic ops by --disable-atomic"
+
+#endif
 
 #endif /* ISC_ATOMIC_H */
index c9333d92830a91ef985481d13260ba7802ba780e..dc00bf310e0e81c935deebc26d0430cfed5b8b5e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: platform.h.in,v 1.38 2005/06/04 05:32:48 jinmei Exp $ */
+/* $Id: platform.h.in,v 1.39 2005/06/16 21:57:59 jinmei Exp $ */
 
 #ifndef ISC_PLATFORM_H
 #define ISC_PLATFORM_H 1
  */
 @ISC_PLATFORM_HAVECMPXCHG@
 
+/*
+ * Define if gcc ASM extension is available
+ */
+@ISC_PLATFORM_USEGCCASM@
+
 /*
  * Define if Tru64 style ASM syntax must be used.
  */
 @ISC_PLATFORM_USEOSFASM@
 
+/*
+ * Define if the standard __asm function must be used.
+ */
+@ISC_PLATFORM_USESTDASM@
+
 #ifndef ISC_PLATFORM_USEDECLSPEC
 #define LIBISC_EXTERNAL_DATA
 #define LIBDNS_EXTERNAL_DATA
index 2d6cdd3e44965e7ccd4cf1142f1bdbba364078f1..cd4fa18d8fc1fe4bc7f90a484316626aae283882 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: atomic.h,v 1.2 2005/06/04 05:32:49 jinmei Exp $ */
+/* $Id: atomic.h,v 1.3 2005/06/16 21:58:00 jinmei Exp $ */
 
 /*
  * This code was written based on FreeBSD's kernel source whose copyright
@@ -59,6 +59,8 @@
 
 #define        ASI_P   0x80            /* Primary Address Space Identifier */
 
+#ifdef ISC_PLATFORM_USEGCCASM
+
 /*
  * This routine atomically increments the value stored in 'p' by 'val', and
  * returns the previous value.
@@ -116,4 +118,10 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
        return (temp);
 }
 
+#else  /* ISC_PLATFORM_USEGCCASM */
+
+#error "unsupported compiler.  disable atomic ops by --disable-atomic"
+
+#endif /* ISC_PLATFORM_USEGCCASM */
+
 #endif /* ISC_ATOMIC_H */
index 807d6967ec8bb130689955e61558716a9a2b1435..f123a54479801034161d080edfa0fa1db15c873d 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: atomic.h,v 1.2 2005/06/04 05:32:50 jinmei Exp $ */
+/* $Id: atomic.h,v 1.3 2005/06/16 21:58:00 jinmei Exp $ */
 
 #ifndef ISC_ATOMIC_H
 #define ISC_ATOMIC_H 1
@@ -22,6 +22,7 @@
 #include <isc/platform.h>
 #include <isc/types.h>
 
+#ifdef ISC_PLATFORM_USEGCCASM
 /*
  * This routine atomically increments the value stored in 'p' by 'val', and
  * returns the previous value.
@@ -55,6 +56,7 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
                 */
                "lock;"         
 #endif
+
                "xchgl %1, %0"
                :
                : "r"(val), "m"(*p)
@@ -80,4 +82,79 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
        return (cmpval);
 }
 
+#elif defined(ISC_PLATFORM_USESTDASM)
+/*
+ * The followings are "generic" assembly code which implements the same
+ * functionality in case the gcc extension cannot be used.  It should be
+ * better to avoid inlining below, since we directly refer to specific
+ * positions of the stack frame, which would not actually point to the
+ * intended address in the embedded mnemonic.
+ *
+ * XXX: this code may also not work on a 64-bit (w/o gcc) machine.
+ */
+#include <isc/util.h>          /* for 'UNUSED' macro */
+
+static isc_int32_t
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
+       UNUSED(p);
+       UNUSED(val);
+
+       __asm (
+               "movl 8(%ebp), %ecx\n"
+               "movl 12(%ebp), %edx\n"
+#ifdef ISC_PLATFORM_USETHREADS
+               "lock;"
+#endif
+               "xadd %edx, (%ecx)\n"
+
+               /*
+                * set the return value directly in the register so that we
+                * can avoid guessing the correct position in the stack for a
+                * local variable.
+                */
+               "movl %edx, %eax"
+               );
+}
+
+static void
+isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
+       UNUSED(p);
+       UNUSED(val);
+
+       __asm (
+               "movl 8(%ebp), %ecx\n"
+               "movl 12(%ebp), %edx\n"
+#ifdef ISC_PLATFORM_USETHREADS
+               "lock;"
+#endif
+               "xchgl (%ecx), %edx\n"
+               );
+}
+
+static isc_int32_t
+isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
+       UNUSED(p);
+       UNUSED(cmpval);
+       UNUSED(val);
+
+       __asm (
+               "movl 8(%ebp), %ecx\n"
+               "movl 12(%ebp), %eax\n" /* must be %eax for cmpxchgl */
+               "movl 16(%ebp), %edx\n"
+#ifdef ISC_PLATFORM_USETHREADS
+               "lock;"
+#endif
+
+               /*
+                * If (%ecx) == %eax then (%ecx) := %edx.
+                % %eax is set to old (%ecx), which will be the return value.
+                */
+               "cmpxchgl %edx, (%ecx)"
+               );
+}
+#else /* !ISC_PLATFORM_USEGCCASM && !ISC_PLATFORM_USESTDASM */
+
+#error "unsupported compiler.  disable atomic ops by --disable-atomic"
+
+#endif
 #endif /* ISC_ATOMIC_H */