diff mbox

libgo patch committed: Implement ____sync_fetch_and_add_4 if needed

Message ID mcripx062tt.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Feb. 4, 2011, 12:49 a.m. UTC
This patch to libgo implements __sync_fetch_and_add_4 if the
compiler/libgcc do not provide it.  The implementation is very dumb but
should suffice to get code working.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r a2c5a4b59a32 libgo/configure.ac
--- a/libgo/configure.ac	Wed Feb 02 17:50:33 2011 -0800
+++ b/libgo/configure.ac	Thu Feb 03 15:07:33 2011 -0800
@@ -396,6 +396,20 @@ 
     [Define to 1 if the compiler provides the __sync_bool_compare_and_swap function for uint32])
 fi
 
+AC_CACHE_CHECK([for __sync_fetch_and_add_4],
+[libgo_cv_func___sync_fetch_and_add_4],
+[AC_LINK_IFELSE([
+typedef unsigned int uint32  __attribute__ ((mode (SI)));
+uint32 i;
+int main() { return __sync_fetch_and_add (&i, 1); }
+],
+[libgo_cv_func___sync_fetch_and_add_4=yes],
+[libgo_cv_func___sync_fetch_and_add_4=no])])
+if test "$libgo_cv_func___sync_fetch_and_add_4" = "yes"; then
+  AC_DEFINE(HAVE_SYNC_FETCH_AND_ADD_4, 1,
+    [Define to 1 if the compiler provides the __sync_fetch_and_add function for uint32])
+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 a2c5a4b59a32 libgo/runtime/go-semacquire.c
--- a/libgo/runtime/go-semacquire.c	Wed Feb 02 17:50:33 2011 -0800
+++ b/libgo/runtime/go-semacquire.c	Thu Feb 03 15:07:33 2011 -0800
@@ -117,3 +117,35 @@ 
       __go_assert (i == 0);
     }
 }
+
+
+#ifndef HAVE_SYNC_FETCH_AND_ADD_4
+
+/* For targets which don't have the required sync support.  Really
+   this should be provided by gcc itself.  FIXME.  */
+
+static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
+
+uint32
+__sync_fetch_and_add_4(uint32*, uint32)
+  __attribute__((visibility("hidden")));
+
+uint32
+__sync_fetch_and_add_4(uint32* ptr, uint32 add)
+{
+  int i;
+  uint32 ret;
+
+  i = pthread_mutex_lock(&sync_lock);
+  __go_assert(i == 0);
+
+  ret = *ptr;
+  *ptr += add;
+
+  i = pthread_mutex_unlock(&sync_lock);
+  __go_assert(i == 0);
+
+  return ret;
+}
+
+#endif