2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

provided __asm version of assembly code for atomic atomic operations

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.)
This commit is contained in:
Tatuya JINMEI 神明達哉
2005-06-16 21:58:00 +00:00
parent 2f3f555262
commit c528bd6986
5 changed files with 155 additions and 17 deletions

View File

@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
esyscmd([sed "s/^/# /" COPYRIGHT])dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl
AC_DIVERT_POP()dnl AC_DIVERT_POP()dnl
AC_REVISION($Revision: 1.378 $) AC_REVISION($Revision: 1.379 $)
AC_INIT(lib/dns/name.c) AC_INIT(lib/dns/name.c)
AC_PREREQ(2.13) AC_PREREQ(2.13)
@@ -1867,7 +1867,6 @@ if test "$use_atomic" = "yes"; then
AC_MSG_CHECKING([architecture type for atomic operations]) AC_MSG_CHECKING([architecture type for atomic operations])
case "$host" in case "$host" in
[i[3456]86-*]|x86_64-*) [i[3456]86-*]|x86_64-*)
# XXX: also need to check portability of the "asm" keyword?
# XXX: some old x86 architectures actualy do not support # XXX: some old x86 architectures actualy do not support
# (some of) these operations. Do we need stricter checks? # (some of) these operations. Do we need stricter checks?
# Note: We currently use the same code for both the x86_32 and # Note: We currently use the same code for both the x86_32 and
@@ -1879,15 +1878,6 @@ if test "$use_atomic" = "yes"; then
alpha*-*) alpha*-*)
have_atomic=yes have_atomic=yes
arch=alpha 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 have_atomic=no
@@ -1897,6 +1887,52 @@ if test "$use_atomic" = "yes"; then
AC_MSG_RESULT($arch) AC_MSG_RESULT($arch)
fi 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 if test "$have_atomic" = "yes"; then
ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1" ISC_PLATFORM_HAVEXADD="#define ISC_PLATFORM_HAVEXADD 1"
ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1" ISC_PLATFORM_HAVECMPXCHG="#define ISC_PLATFORM_HAVECMPXCHG 1"
@@ -1910,7 +1946,10 @@ fi
AC_SUBST(ISC_PLATFORM_HAVEXADD) AC_SUBST(ISC_PLATFORM_HAVEXADD)
AC_SUBST(ISC_PLATFORM_HAVECMPXCHG) AC_SUBST(ISC_PLATFORM_HAVECMPXCHG)
AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE) AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE)
AC_SUBST(ISC_PLATFORM_USEGCCASM)
AC_SUBST(ISC_PLATFORM_USEOSFASM) AC_SUBST(ISC_PLATFORM_USEOSFASM)
AC_SUBST(ISC_PLATFORM_USESTDASM)
ISC_ARCH_DIR=$arch ISC_ARCH_DIR=$arch
AC_SUBST(ISC_ARCH_DIR) AC_SUBST(ISC_ARCH_DIR)

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 * 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:", "2:",
p, cmpval, val)); p, cmpval, val));
} }
#else /* ISC_PLATFORM_USEOSFASM */ #elif defined (ISC_PLATFORM_USEGCCASM)
static inline isc_int32_t static inline isc_int32_t
isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) { isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
isc_int32_t temp, prev; 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); return (prev);
} }
#endif /* ISC_PLATFORM_USEOSFASM */ #else
#error "unsupported compiler. disable atomic ops by --disable-atomic"
#endif
#endif /* ISC_ATOMIC_H */ #endif /* ISC_ATOMIC_H */

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef ISC_PLATFORM_H
#define ISC_PLATFORM_H 1 #define ISC_PLATFORM_H 1
@@ -235,11 +235,21 @@
*/ */
@ISC_PLATFORM_HAVECMPXCHG@ @ISC_PLATFORM_HAVECMPXCHG@
/*
* Define if gcc ASM extension is available
*/
@ISC_PLATFORM_USEGCCASM@
/* /*
* Define if Tru64 style ASM syntax must be used. * Define if Tru64 style ASM syntax must be used.
*/ */
@ISC_PLATFORM_USEOSFASM@ @ISC_PLATFORM_USEOSFASM@
/*
* Define if the standard __asm function must be used.
*/
@ISC_PLATFORM_USESTDASM@
#ifndef ISC_PLATFORM_USEDECLSPEC #ifndef ISC_PLATFORM_USEDECLSPEC
#define LIBISC_EXTERNAL_DATA #define LIBISC_EXTERNAL_DATA
#define LIBDNS_EXTERNAL_DATA #define LIBDNS_EXTERNAL_DATA

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 * This code was written based on FreeBSD's kernel source whose copyright
@@ -59,6 +59,8 @@
#define ASI_P 0x80 /* Primary Address Space Identifier */ #define ASI_P 0x80 /* Primary Address Space Identifier */
#ifdef ISC_PLATFORM_USEGCCASM
/* /*
* This routine atomically increments the value stored in 'p' by 'val', and * This routine atomically increments the value stored in 'p' by 'val', and
* returns the previous value. * 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); return (temp);
} }
#else /* ISC_PLATFORM_USEGCCASM */
#error "unsupported compiler. disable atomic ops by --disable-atomic"
#endif /* ISC_PLATFORM_USEGCCASM */
#endif /* ISC_ATOMIC_H */ #endif /* ISC_ATOMIC_H */

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef ISC_ATOMIC_H
#define ISC_ATOMIC_H 1 #define ISC_ATOMIC_H 1
@@ -22,6 +22,7 @@
#include <isc/platform.h> #include <isc/platform.h>
#include <isc/types.h> #include <isc/types.h>
#ifdef ISC_PLATFORM_USEGCCASM
/* /*
* This routine atomically increments the value stored in 'p' by 'val', and * This routine atomically increments the value stored in 'p' by 'val', and
* returns the previous value. * returns the previous value.
@@ -55,6 +56,7 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
*/ */
"lock;" "lock;"
#endif #endif
"xchgl %1, %0" "xchgl %1, %0"
: :
: "r"(val), "m"(*p) : "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); 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 */ #endif /* ISC_ATOMIC_H */