diff options
author | Ben Cheng <bccheng@google.com> | 2013-03-28 11:14:20 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2013-03-28 12:40:33 -0700 |
commit | af0c51ac87ab2a87caa03fa108f0d164987a2764 (patch) | |
tree | 4b8b470f7c5b69642fdab8d0aa1fbc148d02196b /gcc-4.8/libgo/runtime/thread.c | |
parent | d87cae247d39ebf4f5a6bf25c932a14d2fdb9384 (diff) | |
download | toolchain_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.c | 182 |
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; +} |