diff options
-rw-r--r-- | libgo/config.h.in | 8 | ||||
-rwxr-xr-x | libgo/configure | 58 | ||||
-rw-r--r-- | libgo/configure.ac | 28 | ||||
-rw-r--r-- | libgo/runtime/thread.c | 59 |
4 files changed, 152 insertions, 1 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in index afbb9ee9c53..ae81ff45b47 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -105,10 +105,18 @@ /* Define to 1 if <math.h> defines struct exception */ #undef HAVE_STRUCT_EXCEPTION +/* Define to 1 if the compiler provides the __sync_add_and_fetch function for + uint64 */ +#undef HAVE_SYNC_ADD_AND_FETCH_8 + /* Define to 1 if the compiler provides the __sync_bool_compare_and_swap function for uint32 */ #undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4 +/* Define to 1 if the compiler provides the __sync_bool_compare_and_swap + function for uint64 */ +#undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8 + /* Define to 1 if the compiler provides the __sync_fetch_and_add function for uint32 */ #undef HAVE_SYNC_FETCH_AND_ADD_4 diff --git a/libgo/configure b/libgo/configure index 6bb35a65728..1ce89d22360 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14667,6 +14667,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_bool_compare_and_swap_8" >&5 +$as_echo_n "checking for __sync_bool_compare_and_swap_8... " >&6; } +if test "${libgo_cv_func___sync_bool_compare_and_swap_8+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +typedef unsigned int uint64 __attribute__ ((mode (DI))); +uint64 i; +int main() { return __sync_bool_compare_and_swap (&i, 0, 1); } + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libgo_cv_func___sync_bool_compare_and_swap_8=yes +else + libgo_cv_func___sync_bool_compare_and_swap_8=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_bool_compare_and_swap_8" >&5 +$as_echo "$libgo_cv_func___sync_bool_compare_and_swap_8" >&6; } +if test "$libgo_cv_func___sync_bool_compare_and_swap_8" = "yes"; then + +$as_echo "#define HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8 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 : @@ -14696,6 +14725,35 @@ $as_echo "#define HAVE_SYNC_FETCH_AND_ADD_4 1" >>confdefs.h fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_add_and_fetch_8" >&5 +$as_echo_n "checking for __sync_add_and_fetch_8... " >&6; } +if test "${libgo_cv_func___sync_add_and_fetch_8+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +typedef unsigned int uint64 __attribute__ ((mode (DI))); +uint64 i; +int main() { return __sync_add_and_fetch (&i, 1); } + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libgo_cv_func___sync_add_and_fetch_8=yes +else + libgo_cv_func___sync_add_and_fetch_8=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_add_and_fetch_8" >&5 +$as_echo "$libgo_cv_func___sync_add_and_fetch_8" >&6; } +if test "$libgo_cv_func___sync_add_and_fetch_8" = "yes"; then + +$as_echo "#define HAVE_SYNC_ADD_AND_FETCH_8 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 9c8478de74f..c3c1f5e9452 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -497,6 +497,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_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 @@ if test "$libgo_cv_func___sync_fetch_and_add_4" = "yes"; then [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 --git a/libgo/runtime/thread.c b/libgo/runtime/thread.c index d43e224ffb2..748a62d59f5 100644 --- a/libgo/runtime/thread.c +++ b/libgo/runtime/thread.c @@ -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 @@ __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new) #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 @@ __sync_fetch_and_add_4 (uint32* ptr, uint32 add) #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) |