aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/libgo/runtime/thread.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-03-28 11:14:20 -0700
committerBen Cheng <bccheng@google.com>2013-03-28 12:40:33 -0700
commitaf0c51ac87ab2a87caa03fa108f0d164987a2764 (patch)
tree4b8b470f7c5b69642fdab8d0aa1fbc148d02196b /gcc-4.8/libgo/runtime/thread.c
parentd87cae247d39ebf4f5a6bf25c932a14d2fdb9384 (diff)
downloadtoolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.gz
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.bz2
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.zip
[GCC 4.8] Initial check-in of GCC 4.8.0
Change-Id: I0719d8a6d0f69b367a6ab6f10eb75622dbf12771
Diffstat (limited to 'gcc-4.8/libgo/runtime/thread.c')
-rw-r--r--gcc-4.8/libgo/runtime/thread.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/gcc-4.8/libgo/runtime/thread.c b/gcc-4.8/libgo/runtime/thread.c
new file mode 100644
index 000000000..12d009926
--- /dev/null
+++ b/gcc-4.8/libgo/runtime/thread.c
@@ -0,0 +1,182 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "runtime.h"
+#include "go-assert.h"
+
+/* 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_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;
+
+#endif
+
+#ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
+
+_Bool
+__sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
+ __attribute__ ((visibility ("hidden")));
+
+_Bool
+__sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 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_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
+__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
+
+#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)
+{
+ byte* stack;
+ size_t stacksize;
+ stack_t ss;
+ sigset_t sigs;
+
+ // Initialize signal handling.
+ runtime_m()->gsignal = runtime_malg(32*1024, &stack, &stacksize); // OS X wants >=8K, Linux >=2K
+ ss.ss_sp = stack;
+ ss.ss_flags = 0;
+ ss.ss_size = stacksize;
+ if(sigaltstack(&ss, nil) < 0)
+ *(int *)0xf1 = 0xf1;
+ if (sigemptyset(&sigs) != 0)
+ runtime_throw("sigemptyset");
+ sigprocmask(SIG_SETMASK, &sigs, nil);
+}
+
+uintptr
+runtime_memlimit(void)
+{
+ struct rlimit rl;
+ uintptr used;
+
+ if(getrlimit(RLIMIT_AS, &rl) != 0)
+ return 0;
+ if(rl.rlim_cur >= 0x7fffffff)
+ return 0;
+
+ // Estimate our VM footprint excluding the heap.
+ // Not an exact science: use size of binary plus
+ // some room for thread stacks.
+ used = (64<<20);
+ if(used >= rl.rlim_cur)
+ return 0;
+
+ // If there's not at least 16 MB left, we're probably
+ // not going to be able to do much. Treat as no limit.
+ rl.rlim_cur -= used;
+ if(rl.rlim_cur < (16<<20))
+ return 0;
+
+ return rl.rlim_cur - used;
+}