OSDN Git Service

runtime: Use dl_iterate_phdr to get TLS size.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Jun 2012 00:55:20 +0000 (00:55 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Jun 2012 00:55:20 +0000 (00:55 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188290 138bc75d-0d04-0410-961f-82ee72b054a4

libgo/config.h.in
libgo/configure
libgo/configure.ac
libgo/runtime/proc.c

index eb81c9e..0aef2ce 100644 (file)
@@ -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
 
 /* 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
 
index be9e510..dc85ccf 100755 (executable)
@@ -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"
index 03909d6..0c0dbdd 100644 (file)
@@ -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)
 
index 1a605a1..e3befbe 100644 (file)
@@ -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");