Hello all, Heikki Linnakangas wrote: > An even better approach would be to have a configure test for > __sync_lock_test_and_set. A quick google search suggests that Intel > C Compiler version >= 11.0 also supports __sync_lock_test_and_set, > for example.
Right, http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html explicitly refers to intel CC as well. > It probably makes sense to use it on any platform where it's > defined. Presumably an implementation provided by the compiler is > always going to be at least as good as any magic assembler > incantations we can come up with. I agree. How about a patch like this? It uses builtin atomics if available, and falls back to the custom implementations if not. Note that a simple AC_CHECK_FUNC(__sync_lock_test_and_set) does not work, so I used a slightly more complicated AC_TRY_LINK() which also verifies that __sync_lock_release() is available. The patch is against 9.1.2, but I suppose it also applies to trunk (except perhaps the autogenerated configure part, this needs an autoheader/autoconf run). Thanks for considering, Martin -- Martin Pitt | http://www.piware.de Ubuntu Developer (www.ubuntu.com) | Debian Developer (www.debian.org)
Description: Use gcc/intel cc builtin atomic operations for test-and-set, if available (http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html) Author: Martin Pitt <mp...@debian.org> Index: postgresql-9.1-9.1.2/configure.in =================================================================== --- postgresql-9.1-9.1.2.orig/configure.in 2011-12-01 22:47:20.000000000 +0100 +++ postgresql-9.1-9.1.2/configure.in 2011-12-18 23:30:47.940475128 +0100 @@ -1522,6 +1522,18 @@ AC_SUBST(LDAP_LIBS_FE) AC_SUBST(LDAP_LIBS_BE) +# gcc and intel compiler provide builtin functions for atomic test-and-set +AC_MSG_CHECKING([whether the C compiler provides atomic builtins]) +AC_TRY_LINK([], [int lock = 0; __sync_lock_test_and_set(&lock, 1); __sync_lock_release(&lock);], + [have_cc_atomics="yes"], + [have_cc_atomics="no"] +) +if test "$have_cc_atomics" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CC_ATOMICS, 1, [Define to 1 if compiler provides atomic builtins]) +else + AC_MSG_RESULT(no) +fi # This test makes sure that run tests work at all. Sometimes a shared # library is found by the linker, but the runtime linker can't find it. Index: postgresql-9.1-9.1.2/configure =================================================================== --- postgresql-9.1-9.1.2.orig/configure 2011-12-01 22:47:20.000000000 +0100 +++ postgresql-9.1-9.1.2/configure 2011-12-18 23:31:00.304475596 +0100 @@ -23602,6 +23602,69 @@ +# gcc and intel compiler provide builtin functions for atomic test-and-set +{ $as_echo "$as_me:$LINENO: checking whether the C compiler provides atomic builtins" >&5 +$as_echo_n "checking whether the C compiler provides atomic builtins... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +int lock = 0; __sync_lock_test_and_set(&lock, 1); __sync_lock_release(&lock); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + have_cc_atomics="yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + have_cc_atomics="no" + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +if test "$have_cc_atomics" = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CC_ATOMICS 1 +_ACEOF + +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi # This test makes sure that run tests work at all. Sometimes a shared # library is found by the linker, but the runtime linker can't find it. Index: postgresql-9.1-9.1.2/src/include/pg_config.h.in =================================================================== --- postgresql-9.1-9.1.2.orig/src/include/pg_config.h.in 2011-12-01 22:47:20.000000000 +0100 +++ postgresql-9.1-9.1.2/src/include/pg_config.h.in 2011-12-18 23:30:34.752474625 +0100 @@ -87,6 +87,9 @@ /* Define to 1 if you have the `cbrt' function. */ #undef HAVE_CBRT +/* Define to 1 if compiler provides atomic builtins */ +#undef HAVE_CC_ATOMICS + /* Define to 1 if you have the `class' function. */ #undef HAVE_CLASS Index: postgresql-9.1-9.1.2/src/include/storage/s_lock.h =================================================================== --- postgresql-9.1-9.1.2.orig/src/include/storage/s_lock.h 2011-12-01 22:47:20.000000000 +0100 +++ postgresql-9.1-9.1.2/src/include/storage/s_lock.h 2011-12-18 23:30:35.296474646 +0100 @@ -77,8 +77,26 @@ #ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ +/************************************************************************* + * Use compiler provided atomic builtins if available (in particular, gcc and + * Intel provide them for many platforms), as we are unlikely to come up with + * better ones. + */ +#ifdef HAVE_CC_ATOMICS +#define HAS_TEST_AND_SET +typedef int slock_t; + +#define TAS(lock) tas(lock) +#define S_UNLOCK(lock) __sync_lock_release(lock) + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set (lock, 1); +} +#endif -#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#if !defined(HAS_TEST_AND_SET) && (defined(__GNUC__) || defined(__INTEL_COMPILER)) /************************************************************************* * All the gcc inlines * Gcc consistently defines the CPU as __cpu__.
signature.asc
Description: Digital signature