From 410ab087fadc70f263156da4e47695bcbc50a0ee Mon Sep 17 00:00:00 2001 From: Niels Grewe Date: Thu, 26 May 2011 18:37:58 +0000 Subject: [PATCH] Attempt to detect the flags needed to enable compiler intrinsics for atomic operations. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@33134 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 10 +++ Headers/GNUstepBase/config.h.in | 6 ++ Source/NSObject.m | 24 +++--- configure | 126 ++++++++++++++++++++++++++++++++ configure.ac | 64 ++++++++++++++++ 5 files changed, 218 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92b49d6dd..3c0ff2a65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2011-05-26 Niels Grewe + + * configure.ac: Add test to check for availability of atomic builtins. + * configure: Regenerate. + * Headers/GNUstepBase/config.h.in: Regenerate. + * Source/NSObject.m: Fix typo. + + Attempt to set the compiler and linker flags needed to enable compiler + intrinsics for atomic operations on platforms where those are available. + 2011-05-26 18:29 David Chisnall * Source/simple-load.h: diff --git a/Headers/GNUstepBase/config.h.in b/Headers/GNUstepBase/config.h.in index 1351add4e..5c4dadea4 100644 --- a/Headers/GNUstepBase/config.h.in +++ b/Headers/GNUstepBase/config.h.in @@ -699,6 +699,9 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME +/* Define to the home page for this package. */ +#undef PACKAGE_URL + /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -738,6 +741,9 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Define if the compiler provides builtins for atomic operations */ +#undef USE_ATOMIC_BUILTINS + /* Define if using the ffcall library for invocations */ #undef USE_FFCALL diff --git a/Source/NSObject.m b/Source/NSObject.m index 991581803..08e742564 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -105,7 +105,7 @@ static Class NSConstantStringClass; - (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector; @end -@interface GSContentAccessingProxy : NSProxy +@interface GSContentAccessingProxy : NSProxy { NSObject *object; } @@ -113,7 +113,7 @@ static Class NSConstantStringClass; @end /* - * allocationLock is needed when running multi-threaded for + * allocationLock is needed when running multi-threaded for * protecting the map table of zombie information. */ static NSLock *allocationLock; @@ -209,7 +209,7 @@ typedef int32_t volatile *gsatomic_t; #define GSAtomicDecrement(X) InterlockedDecrement((LONG volatile*)X) -#elif defined(__llvm__) || (defined(USE_ATOMIC_BUILDINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))) +#elif defined(__llvm__) || (defined(USE_ATOMIC_BUILTINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))) /* Use the GCC atomic operations with recent GCC versions */ typedef int32_t volatile *gsatomic_t; @@ -247,7 +247,7 @@ GSAtomicDecrement(gsatomic_t X) register int tmp; __asm__ __volatile__ ( "movl $1, %0\n" - "negl %0\n" + "negl %0\n" "lock xaddl %0, %1" :"=r" (tmp), "=m" (*X) :"r" (tmp), "m" (*X) @@ -561,8 +561,8 @@ NSIncrementExtraRefCount(id anObject) #define AADD(c, o) GSDebugAllocationAdd(c, o) #define AREM(c, o) GSDebugAllocationRemove(c, o) #else -#define AADD(c, o) -#define AREM(c, o) +#define AADD(c, o) +#define AREM(c, o) #endif static SEL cxx_construct, cxx_destruct; @@ -574,7 +574,7 @@ static SEL cxx_construct, cxx_destruct; * -.cxx_destruct. The -.cxx_construct methods must be called in order from * the root class to all subclasses, to ensure that subclass ivars are * initialised after superclass ones. This must be done in reverse for - * destruction. + * destruction. * * This function first calls itself recursively on the superclass, to get the * IMP for the constructor function in the superclass. It then compares the @@ -630,7 +630,7 @@ inline void NSDeallocateObject(id anObject) { } -#elif GS_WITH_GC +#elif GS_WITH_GC inline NSZone * GSObjCZone(NSObject *object) @@ -918,7 +918,7 @@ GSGarbageCollectorLog(char *msg, GC_word arg) * Semi-private function in libobjc2 that initialises the classes used for * blocks. */ -extern BOOL +extern BOOL objc_create_block_classes_as_subclasses_of(Class super); + (void) load @@ -941,8 +941,8 @@ objc_create_block_classes_as_subclasses_of(Class super); #ifdef __MINGW__ { // See libgnustep-base-entry.m - extern void gnustep_base_socket_init(void); - gnustep_base_socket_init(); + extern void gnustep_base_socket_init(void); + gnustep_base_socket_init(); } #else /* __MINGW__ */ @@ -2407,7 +2407,7 @@ objc_create_block_classes_as_subclasses_of(Class super); } @end -@implementation GSContentAccessingProxy +@implementation GSContentAccessingProxy - (void) dealloc { [object endContentAccess]; diff --git a/configure b/configure index ad9f0a0ad..0992d1148 100755 --- a/configure +++ b/configure @@ -5063,6 +5063,132 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + +#-------------------------------------------------------------------- +# Check how to enable builtins for atomic operations +#-------------------------------------------------------------------- + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports atomic operations" >&5 +$as_echo_n "checking whether the compiler supports atomic operations... " >&6; }; + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +typedef int atomic; +int +main () +{ +atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + have_atomic=yes +else + have_atomic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext; + if test "$have_atomic" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + +$as_echo "#define USE_ATOMIC_BUILTINS 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + fi +if test "$CC" = "gcc"; then + saved_CFLAGS="$CFLAGS"; + ATOMIC_CFLAGS=""; + + # FIXME: Forcing -march=i568 for any i568 or later CPU is a stop gap measure + # to make the compiler emit native assembly for atomic operations on i586 or + # latter processors (GCC by defaults emits code compatible with the original + # i386 and requires library functions to emulate atomic operations). When + # gnustep-make takes care of this kind of target setting, the check can safely + # be removed. + case "$target_cpu" in + i586*|i686*|i786*) + ATOMIC_CFLAGS="-march=i586"; + CFLAGS="$saved_CFLAGS $ATOMIC_CFLAGS"; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking checking whether atomic operations require an external library" >&5 +$as_echo_n "checking checking whether atomic operations require an external library... " >&6; }; + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +typedef int atomic; +int +main () +{ +atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + need_linkage=no +else + need_linkage=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext; + + if test "$need_linkage" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + saved_LDFLAGS="$LDFLAGS"; + LDFLAGS="$saved_LDFLAGS -lgcc"; + { $as_echo "$as_me:${as_lineno-$LINENO}: checking checking for atomic operations from libgcc" >&5 +$as_echo_n "checking checking for atomic operations from libgcc... " >&6; }; + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +typedef int atomic; +int +main () +{ +atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + atomic_in_libgcc=yes +else + atomic_in_libgcc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext; + if test "$atomic_in_libgcc" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + LIBS="$LIBS -lgcc"; + +$as_echo "#define USE_ATOMIC_BUILTINS 1" >>confdefs.h + + else + LDFLAGS="$saved_LDFLAGS"; + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; + fi + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + # Extract the first word of "whoami", so it can be a program name with args. set dummy whoami; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 diff --git a/configure.ac b/configure.ac index 25bfa77d2..bf21999a7 100644 --- a/configure.ac +++ b/configure.ac @@ -1006,6 +1006,70 @@ AC_PROG_CC AC_PROG_CPP AC_USE_SYSTEM_EXTENSIONS + +#-------------------------------------------------------------------- +# Check how to enable builtins for atomic operations +#-------------------------------------------------------------------- + +AC_LANG_PUSH(C) +AC_MSG_CHECKING([whether the compiler supports atomic operations]); + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[typedef int atomic;]], + [[atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1);]])], + have_atomic=yes, + have_atomic=no); + if test "$have_atomic" = "yes"; then + AC_MSG_RESULT([yes]); + AC_DEFINE(USE_ATOMIC_BUILTINS,1, + [Define if the compiler provides builtins for atomic operations]) + else + AC_MSG_RESULT([no]); + fi +if test "$CC" = "gcc"; then + saved_CFLAGS="$CFLAGS"; + ATOMIC_CFLAGS=""; + + # FIXME: Forcing -march=i568 for any i568 or later CPU is a stop gap measure + # to make the compiler emit native assembly for atomic operations on i586 or + # latter processors (GCC by defaults emits code compatible with the original + # i386 and requires library functions to emulate atomic operations). When + # gnustep-make takes care of this kind of target setting, the check can safely + # be removed. + case "$target_cpu" in + i586*|i686*|i786*) + ATOMIC_CFLAGS="-march=i586"; + CFLAGS="$saved_CFLAGS $ATOMIC_CFLAGS"; + esac + AC_MSG_CHECKING([checking whether atomic operations require an external library]); + AC_LINK_IFELSE([AC_LANG_PROGRAM([[typedef int atomic;]], + [[atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1);]])], + need_linkage=no, + need_linkage=yes); + + if test "$need_linkage" = "no"; then + AC_MSG_RESULT([no]); + else + AC_MSG_RESULT([yes]); + saved_LDFLAGS="$LDFLAGS"; + LDFLAGS="$saved_LDFLAGS -lgcc"; + AC_MSG_CHECKING([checking for atomic operations from libgcc]); + AC_LINK_IFELSE([AC_LANG_PROGRAM([[typedef int atomic;]], + [[atomic x; atomic y; __sync_bool_compare_and_swap(&x, y, y + 1);]])], + atomic_in_libgcc=yes, + atomic_in_libgcc=no); + if test "$atomic_in_libgcc" = "yes"; then + AC_MSG_RESULT([yes]); + LIBS="$LIBS -lgcc"; + AC_DEFINE(USE_ATOMIC_BUILTINS,1, + [Define if the compiler provides builtins for atomic operations]) + else + LDFLAGS="$saved_LDFLAGS"; + AC_MSG_RESULT([no]); + fi + fi +fi +AC_LANG_POP(C) + + AC_PATH_PROG(WHOAMI, whoami, echo, $PATH:/usr/ucb) #--------------------------------------------------------------------