diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-04 00:49:47 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-04 00:49:47 +0000 |
commit | cb6f50ce2caf83ac6c0908700851650590c9498a (patch) | |
tree | 76e7890cb0df366dd7820b88386401a0f81c6dc1 /libgo | |
parent | a40344730aa1ccc7ba84749769dd5fbaa47471f8 (diff) | |
download | gcc-cb6f50ce2caf83ac6c0908700851650590c9498a.tar.gz |
Implement __sync_fetch_and_add_4 if necessary.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169820 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/config.h.in | 4 | ||||
-rw-r--r-- | libgo/configure | 29 | ||||
-rw-r--r-- | libgo/configure.ac | 14 | ||||
-rw-r--r-- | libgo/runtime/go-semacquire.c | 32 |
4 files changed, 79 insertions, 0 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in index 22d6f721e2d..18a51cc8f02 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -43,6 +43,10 @@ function for uint32 */ #undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4 +/* Define to 1 if the compiler provides the __sync_fetch_and_add function for + uint32 */ +#undef HAVE_SYNC_FETCH_AND_ADD_4 + /* Define to 1 if you have the <syscall.h> header file. */ #undef HAVE_SYSCALL_H diff --git a/libgo/configure b/libgo/configure index ddb61c00262..fbaac8e3d61 100644 --- a/libgo/configure +++ b/libgo/configure @@ -14206,6 +14206,35 @@ $as_echo "#define HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4 1" >>confdefs.h fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_fetch_and_add_4" >&5 +$as_echo_n "checking for __sync_fetch_and_add_4... " >&6; } +if test "${libgo_cv_func___sync_fetch_and_add_4+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +typedef unsigned int uint32 __attribute__ ((mode (SI))); +uint32 i; +int main() { return __sync_fetch_and_add (&i, 1); } + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libgo_cv_func___sync_fetch_and_add_4=yes +else + libgo_cv_func___sync_fetch_and_add_4=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_func___sync_fetch_and_add_4" >&5 +$as_echo "$libgo_cv_func___sync_fetch_and_add_4" >&6; } +if test "$libgo_cv_func___sync_fetch_and_add_4" = "yes"; then + +$as_echo "#define HAVE_SYNC_FETCH_AND_ADD_4 1" >>confdefs.h + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -minline-all-stringops" >&5 $as_echo_n "checking whether compiler supports -minline-all-stringops... " >&6; } if test "${libgo_cv_c_stringops+set}" = set; then : diff --git a/libgo/configure.ac b/libgo/configure.ac index 1c75b3ef6d2..da56610b579 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -396,6 +396,20 @@ if test "$libgo_cv_func___sync_bool_compare_and_swap_4" = "yes"; then [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 --git a/libgo/runtime/go-semacquire.c b/libgo/runtime/go-semacquire.c index 67a86ef695f..24c6a7388f6 100644 --- a/libgo/runtime/go-semacquire.c +++ b/libgo/runtime/go-semacquire.c @@ -117,3 +117,35 @@ semrelease (uint32 *addr) __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 |