Patchwork libgo patch committed: Define more __sync function

login
register
mail settings
Submitter Ian Taylor
Date Feb. 12, 2012, 6:23 a.m.
Message ID <mcr39agin8v.fsf@dhcp-172-18-216-180.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/140802/
State New
Headers show

Comments

Ian Taylor - Feb. 12, 2012, 6:23 a.m.
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

Patch

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)