diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-07 00:55:20 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-07 00:55:20 +0000 |
commit | a01550acfc47492bf127b83b92b14471b020041b (patch) | |
tree | df3ab096fe1132c25cca2f3c18db4ac5133baf52 /libgo | |
parent | fd4076faf16b0590f625bb827449ee78b1b2d99c (diff) | |
download | gcc-a01550acfc47492bf127b83b92b14471b020041b.tar.gz |
runtime: Use dl_iterate_phdr to get TLS size.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188290 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/config.h.in | 6 | ||||
-rwxr-xr-x | libgo/configure | 2 | ||||
-rw-r--r-- | libgo/configure.ac | 2 | ||||
-rw-r--r-- | libgo/runtime/proc.c | 89 |
4 files changed, 63 insertions, 36 deletions
diff --git a/libgo/config.h.in b/libgo/config.h.in index eb81c9ee715..0aef2ce7b07 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -21,6 +21,9 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `dl_iterate_phdr' function. */ +#undef HAVE_DL_ITERATE_PHDR + /* Define to 1 if you have the `epoll_create1' function. */ #undef HAVE_EPOLL_CREATE1 @@ -286,9 +289,6 @@ /* Define to 1 if you have the `wait4' function. */ #undef HAVE_WAIT4 -/* Define to 1 if you have the `_dl_get_tls_static_info' function. */ -#undef HAVE__DL_GET_TLS_STATIC_INFO - /* Define if the C++ compiler is configured for setjmp/longjmp exceptions. */ #undef LIBGO_SJLJ_EXCEPTIONS diff --git a/libgo/configure b/libgo/configure index be9e510ce25..dc85ccfa9db 100755 --- a/libgo/configure +++ b/libgo/configure @@ -14584,7 +14584,7 @@ else fi -for ac_func in strerror_r strsignal wait4 mincore setenv _dl_get_tls_static_info +for ac_func in strerror_r strsignal wait4 mincore setenv dl_iterate_phdr do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/libgo/configure.ac b/libgo/configure.ac index 03909d6046c..0c0dbdd46a9 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -481,7 +481,7 @@ fi AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes) -AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv _dl_get_tls_static_info) +AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv dl_iterate_phdr) AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes) AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes) diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 1a605a1921c..e3befbec996 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -8,6 +8,11 @@ #include <unistd.h> #include "config.h" + +#ifdef HAVE_DL_ITERATE_PHDR +#include <link.h> +#endif + #include "runtime.h" #include "arch.h" #include "defs.h" @@ -36,12 +41,12 @@ extern void __splitstack_block_signals_context (void *context[10], int *, #endif +#ifndef PTHREAD_STACK_MIN +# define PTHREAD_STACK_MIN 8192 +#endif + #if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK) -# ifdef PTHREAD_STACK_MIN -# define StackMin PTHREAD_STACK_MIN -# else -# define StackMin 8192 -# endif +# define StackMin PTHREAD_STACK_MIN #else # define StackMin 2 * 1024 * 1024 #endif @@ -138,6 +143,46 @@ runtime_m(void) int32 runtime_gcwaiting; +// The static TLS size. See runtime_newm. +static int tlssize; + +#ifdef HAVE_DL_ITERATE_PHDR + +// Called via dl_iterate_phdr. + +static int +addtls(struct dl_phdr_info* info, size_t size __attribute__ ((unused)), void *data) +{ + size_t *total = (size_t *)data; + unsigned int i; + + for(i = 0; i < info->dlpi_phnum; ++i) { + if(info->dlpi_phdr[i].p_type == PT_TLS) + *total += info->dlpi_phdr[i].p_memsz; + } + return 0; +} + +// Set the total TLS size. + +static void +inittlssize() +{ + size_t total = 0; + + dl_iterate_phdr(addtls, (void *)&total); + tlssize = total; +} + +#else + +static void +inittlssize() +{ +} + +#endif + // Go scheduler // // The go scheduler's job is to match ready-to-run goroutines (`g's) @@ -393,6 +438,7 @@ runtime_schedinit(void) g->m = m; initcontext(); + inittlssize(); m->nomemprof++; runtime_mallocinit(); @@ -1116,34 +1162,15 @@ runtime_newm(void) if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) runtime_throw("pthread_attr_setdetachstate"); -#ifndef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 8192 -#endif - stacksize = PTHREAD_STACK_MIN; -#if 0 -#ifdef HAVE__DL_GET_TLS_STATIC_INFO - { - /* On GNU/Linux the static TLS size is taken out of - the stack size, and we get an error or a crash if - there is not enough stack space left. Add it back - in if we can, in case the program uses a lot of TLS - space. */ -#ifndef internal_function -#ifdef __i386__ -#define internal_function __attribute__ ((regparm (3), stdcall)) -#else -#define internal_function -#endif -#endif - extern void _dl_get_tls_static_info(size_t*, size_t*) internal_function; - size_t tlssize, tlsalign; - _dl_get_tls_static_info(&tlssize, &tlsalign); - stacksize += tlssize; - } -#endif -#endif + // With glibc before version 2.16 the static TLS size is taken + // out of the stack size, and we get an error or a crash if + // there is not enough stack space left. Add it back in if we + // can, in case the program uses a lot of TLS space. FIXME: + // This can be disabled in glibc 2.16 and later, if the bug is + // indeed fixed then. + stacksize += tlssize; if(pthread_attr_setstacksize(&attr, stacksize) != 0) runtime_throw("pthread_attr_setstacksize"); |