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.)
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)
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
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
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"
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)
* 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
"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;
return (prev);
}
-#endif /* ISC_PLATFORM_USEOSFASM */
+#else
+
+#error "unsupported compiler. disable atomic ops by --disable-atomic"
+
+#endif
#endif /* ISC_ATOMIC_H */
* 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
* 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
#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.
return (temp);
}
+#else /* ISC_PLATFORM_USEGCCASM */
+
+#error "unsupported compiler. disable atomic ops by --disable-atomic"
+
+#endif /* ISC_PLATFORM_USEGCCASM */
+
#endif /* ISC_ATOMIC_H */
* 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
#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.
*/
"lock;"
#endif
+
"xchgl %1, %0"
:
: "r"(val), "m"(*p)
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 */