This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
libgo patch committed: Define more __sync function
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Sat, 11 Feb 2012 22:23:12 -0800
- Subject: libgo patch committed: Define more __sync function
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)