aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/thread.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-02-12 06:23:08 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-02-12 06:23:08 +0000
commit12e3c3961436e0bc19f7fcbf7dd5ba6d556b0803 (patch)
treed088dbdf76ccf89230dc607d000488ace3bb43e9 /libgo/runtime/thread.c
parent22d87829789be10d2b3a88c2ee6253d88ff88d6b (diff)
downloadgcc-12e3c3961436e0bc19f7fcbf7dd5ba6d556b0803.zip
gcc-12e3c3961436e0bc19f7fcbf7dd5ba6d556b0803.tar.gz
gcc-12e3c3961436e0bc19f7fcbf7dd5ba6d556b0803.tar.bz2
re PR go/52084 (go tests fail to link on powerpc-linux-gnu (undefined reference to __sync_add_and_fetch_8))
PR go/52084 libgo: Provide more __sync functions if required. From-SVN: r184138
Diffstat (limited to 'libgo/runtime/thread.c')
-rw-r--r--libgo/runtime/thread.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/libgo/runtime/thread.c b/libgo/runtime/thread.c
index d43e224..748a62d5 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)