about summary refs log tree commit diff
path: root/nptl/nptl-init.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-03-01 14:15:39 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-03-01 14:15:39 +0530
commite23872c8db1fb26713b9c15b12686ac7a0077576 (patch)
treea7fa040afb53ba1f5bd98bb33f214aa32e3729b8 /nptl/nptl-init.c
parentfd6cdc6da490616f4d381f4d44f03d61f64da2ba (diff)
downloadglibc-e23872c8db1fb26713b9c15b12686ac7a0077576.tar.gz
glibc-e23872c8db1fb26713b9c15b12686ac7a0077576.tar.xz
glibc-e23872c8db1fb26713b9c15b12686ac7a0077576.zip
Set default stack size from program environment
New environment variable GLIBC_PTHREAD_DEFAULT_STACKSIZE to do this.
Diffstat (limited to 'nptl/nptl-init.c')
-rw-r--r--nptl/nptl-init.c74
1 files changed, 52 insertions, 22 deletions
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 19e6616420..50148224e8 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -276,8 +276,26 @@ extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
 /* This can be set by the debugger before initialization is complete.  */
 static bool __nptl_initial_report_events __attribute_used__;
 
+static void
+set_default_stacksize (size_t stacksize)
+{
+  if (stacksize < PTHREAD_STACK_MIN)
+    stacksize = PTHREAD_STACK_MIN;
+
+  /* Make sure it meets the minimum size that allocate_stack
+     (allocatestack.c) will demand, which depends on the page size.  */
+  const uintptr_t pagesz = GLRO(dl_pagesize);
+  const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
+
+  if (stacksize < minstack)
+    stacksize = minstack;
+
+  /* Round the resource limit up to page size.  */
+  stacksize = (stacksize + pagesz - 1) & -pagesz;
+  __default_stacksize = stacksize;
+}
 void
-__pthread_initialize_minimal_internal (void)
+__pthread_initialize_minimal_internal (int argc, char **argv, char **envp)
 {
 #ifndef SHARED
   /* Unlike in the dynamically linked case the dynamic linker has not
@@ -401,29 +419,41 @@ __pthread_initialize_minimal_internal (void)
 
   __static_tls_size = roundup (__static_tls_size, static_tls_align);
 
-  /* Determine the default allowed stack size.  This is the size used
-     in case the user does not specify one.  */
-  struct rlimit limit;
-  if (getrlimit (RLIMIT_STACK, &limit) != 0
-      || limit.rlim_cur == RLIM_INFINITY)
-    /* The system limit is not usable.  Use an architecture-specific
-       default.  */
-    limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
-  else if (limit.rlim_cur < PTHREAD_STACK_MIN)
-    /* The system limit is unusably small.
-       Use the minimal size acceptable.  */
-    limit.rlim_cur = PTHREAD_STACK_MIN;
+  /* Initialize the environment.  libc.so gets initialized after us due to a
+     circular dependency and hence __environ is not available otherwise.  */
+    __environ = envp;
 
-  /* Make sure it meets the minimum size that allocate_stack
-     (allocatestack.c) will demand, which depends on the page size.  */
-  const uintptr_t pagesz = GLRO(dl_pagesize);
-  const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
-  if (limit.rlim_cur < minstack)
-    limit.rlim_cur = minstack;
+#ifndef SHARED
+    __libc_init_secure ();
+#endif
 
-  /* Round the resource limit up to page size.  */
-  limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
-  __default_stacksize = limit.rlim_cur;
+  size_t stacksize = 0;
+  char *envval = __libc_secure_getenv ("GLIBC_PTHREAD_DEFAULT_STACKSIZE");
+
+  if (__glibc_unlikely (envval != NULL && envval[0] != '\0'))
+    {
+      char *env_conv = envval;
+      size_t ret = strtoul (envval, &env_conv, 0);
+
+      if (*env_conv == '\0' && env_conv != envval)
+	stacksize = ret;
+    }
+
+  if (stacksize == 0)
+    {
+      /* Determine the default allowed stack size.  This is the size used
+	 in case the user does not specify one.  */
+      struct rlimit limit;
+      if (getrlimit (RLIMIT_STACK, &limit) != 0
+	  || limit.rlim_cur == RLIM_INFINITY)
+	/* The system limit is not usable.  Use an architecture-specific
+	   default.  */
+	stacksize = ARCH_STACK_DEFAULT_SIZE;
+      else
+	stacksize = limit.rlim_cur;
+    }
+
+  set_default_stacksize (stacksize);
 
 #ifdef SHARED
   /* Transfer the old value from the dynamic linker's internal location.  */