This patch to libgo defines some more __sync functions that may be missing on some systems. PR 52084 reports that these are missing on PowerPC GNU/Linux.
I'll convert these to the new __atomic functions in gcc 4.8 when the atomic library is available. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu (which proves little since that systems does not require the new functions). Committed to mainline. Ian
diff -r ac108b661568 libgo/configure.ac --- a/libgo/configure.ac Sat Feb 11 21:55:33 2012 -0800 +++ b/libgo/configure.ac Sat Feb 11 22:18:34 2012 -0800 @@ -497,6 +497,20 @@ [Define to 1 if the compiler provides the __sync_bool_compare_and_swap function for uint32]) fi +AC_CACHE_CHECK([for __sync_bool_compare_and_swap_8], +[libgo_cv_func___sync_bool_compare_and_swap_8], +[AC_LINK_IFELSE([ +typedef unsigned int uint64 __attribute__ ((mode (DI))); +uint64 i; +int main() { return __sync_bool_compare_and_swap (&i, 0, 1); } +], +[libgo_cv_func___sync_bool_compare_and_swap_8=yes], +[libgo_cv_func___sync_bool_compare_and_swap_8=no])]) +if test "$libgo_cv_func___sync_bool_compare_and_swap_8" = "yes"; then + AC_DEFINE(HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8, 1, + [Define to 1 if the compiler provides the __sync_bool_compare_and_swap function for uint64]) +fi + AC_CACHE_CHECK([for __sync_fetch_and_add_4], [libgo_cv_func___sync_fetch_and_add_4], [AC_LINK_IFELSE([ @@ -511,6 +525,20 @@ [Define to 1 if the compiler provides the __sync_fetch_and_add function for uint32]) fi +AC_CACHE_CHECK([for __sync_add_and_fetch_8], +[libgo_cv_func___sync_add_and_fetch_8], +[AC_LINK_IFELSE([ +typedef unsigned int uint64 __attribute__ ((mode (DI))); +uint64 i; +int main() { return __sync_add_and_fetch (&i, 1); } +], +[libgo_cv_func___sync_add_and_fetch_8=yes], +[libgo_cv_func___sync_add_and_fetch_8=no])]) +if test "$libgo_cv_func___sync_add_and_fetch_8" = "yes"; then + AC_DEFINE(HAVE_SYNC_ADD_AND_FETCH_8, 1, + [Define to 1 if the compiler provides the __sync_add_and_fetch function for uint64]) +fi + dnl For x86 we want to use the -minline-all-stringops option to avoid dnl forcing a stack split when calling memcpy and friends. AC_CACHE_CHECK([whether compiler supports -minline-all-stringops], diff -r ac108b661568 libgo/runtime/thread.c --- a/libgo/runtime/thread.c Sat Feb 11 21:55:33 2012 -0800 +++ b/libgo/runtime/thread.c Sat Feb 11 22:18:34 2012 -0800 @@ -11,7 +11,7 @@ /* For targets which don't have the required sync support. Really these should be provided by gcc itself. FIXME. */ -#if !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4) || !defined (HAVE_SYNC_FETCH_AND_ADD_4) +#if !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4) || !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8) || !defined (HAVE_SYNC_FETCH_AND_ADD_4) || !defined (HAVE_SYNC_ADD_AND_FETCH_8) static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER; @@ -48,6 +48,37 @@ #endif +#ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8 + +_Bool +__sync_bool_compare_and_swap_8 (uint64*, uint64, uint64) + __attribute__ ((visibility ("hidden"))); + +_Bool +__sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new) +{ + int i; + _Bool ret; + + i = pthread_mutex_lock (&sync_lock); + __go_assert (i == 0); + + if (*ptr != old) + ret = 0; + else + { + *ptr = new; + ret = 1; + } + + i = pthread_mutex_unlock (&sync_lock); + __go_assert (i == 0); + + return ret; +} + +#endif + #ifndef HAVE_SYNC_FETCH_AND_ADD_4 uint32 @@ -74,6 +105,32 @@ #endif +#ifndef HAVE_SYNC_ADD_AND_FETCH_8 + +uint64 +__sync_add_and_fetch_8 (uint64*, uint64) + __attribute__ ((visibility ("hidden"))); + +uint64 +__sync_add_and_fetch_8 (uint64* ptr, uint64 add) +{ + int i; + uint64 ret; + + i = pthread_mutex_lock (&sync_lock); + __go_assert (i == 0); + + *ptr += add; + ret = *ptr; + + i = pthread_mutex_unlock (&sync_lock); + __go_assert (i == 0); + + return ret; +} + +#endif + // Called to initialize a new m (including the bootstrap m). void runtime_minit(void)