diff --git a/configure.in b/configure.in index f3992b1881..16428beed9 100644 --- a/configure.in +++ b/configure.in @@ -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) diff --git a/lib/isc/alpha/include/isc/atomic.h b/lib/isc/alpha/include/isc/atomic.h index 83fe91d08b..2eb4a1715d 100644 --- a/lib/isc/alpha/include/isc/atomic.h +++ b/lib/isc/alpha/include/isc/atomic.h @@ -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 */ diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in index c9333d9283..dc00bf310e 100644 --- a/lib/isc/include/isc/platform.h.in +++ b/lib/isc/include/isc/platform.h.in @@ -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 @@ -235,11 +235,21 @@ */ @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 diff --git a/lib/isc/sparc64/include/isc/atomic.h b/lib/isc/sparc64/include/isc/atomic.h index 2d6cdd3e44..cd4fa18d8f 100644 --- a/lib/isc/sparc64/include/isc/atomic.h +++ b/lib/isc/sparc64/include/isc/atomic.h @@ -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 */ diff --git a/lib/isc/x86_32/include/isc/atomic.h b/lib/isc/x86_32/include/isc/atomic.h index 807d6967ec..f123a54479 100644 --- a/lib/isc/x86_32/include/isc/atomic.h +++ b/lib/isc/x86_32/include/isc/atomic.h @@ -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 #include +#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 /* 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 */