|
|
29e444 |
diff -pruN glibc-2.17-c758a686/csu/libc-start.c glibc-2.17-c758a686.new/csu/libc-start.c
|
|
|
29e444 |
--- glibc-2.17-c758a686/csu/libc-start.c 2012-12-25 08:32:13.000000000 +0530
|
|
|
29e444 |
+++ glibc-2.17-c758a686.new/csu/libc-start.c 2013-07-30 11:46:44.571901690 +0530
|
|
|
29e444 |
@@ -32,7 +32,7 @@ extern int __libc_multiple_libcs;
|
|
|
29e444 |
#include <tls.h>
|
|
|
29e444 |
#ifndef SHARED
|
|
|
29e444 |
# include <dl-osinfo.h>
|
|
|
29e444 |
-extern void __pthread_initialize_minimal (void);
|
|
|
29e444 |
+extern void __pthread_initialize_minimal (int, char **, char **);
|
|
|
29e444 |
# ifndef THREAD_SET_STACK_GUARD
|
|
|
29e444 |
/* Only exported for architectures that don't store the stack guard canary
|
|
|
29e444 |
in thread local area. */
|
|
|
29e444 |
@@ -175,7 +175,7 @@ LIBC_START_MAIN (int (*main) (int, char
|
|
|
29e444 |
/* Initialize the thread library at least a bit since the libgcc
|
|
|
29e444 |
functions are using thread functions if these are available and
|
|
|
29e444 |
we need to setup errno. */
|
|
|
29e444 |
- __pthread_initialize_minimal ();
|
|
|
29e444 |
+ __pthread_initialize_minimal (argc, argv, __environ);
|
|
|
29e444 |
|
|
|
29e444 |
/* Set up the stack checker's canary. */
|
|
|
29e444 |
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
|
|
|
29e444 |
diff -pruN glibc-2.17-c758a686/csu/libc-tls.c glibc-2.17-c758a686.new/csu/libc-tls.c
|
|
|
29e444 |
--- glibc-2.17-c758a686/csu/libc-tls.c 2012-12-25 08:32:13.000000000 +0530
|
|
|
29e444 |
+++ glibc-2.17-c758a686.new/csu/libc-tls.c 2013-07-30 11:46:44.572901690 +0530
|
|
|
29e444 |
@@ -243,7 +243,7 @@ _dl_tls_setup (void)
|
|
|
29e444 |
not used. */
|
|
|
29e444 |
void
|
|
|
29e444 |
__attribute__ ((weak))
|
|
|
29e444 |
-__pthread_initialize_minimal (void)
|
|
|
29e444 |
+__pthread_initialize_minimal (int argc, char **argv, char **envp)
|
|
|
29e444 |
{
|
|
|
29e444 |
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
|
|
|
29e444 |
}
|
|
|
29e444 |
diff -pruN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686.new/nptl/Makefile
|
|
|
29e444 |
--- glibc-2.17-c758a686/nptl/Makefile 2013-07-30 11:46:34.909902026 +0530
|
|
|
29e444 |
+++ glibc-2.17-c758a686.new/nptl/Makefile 2013-07-30 11:46:44.573901690 +0530
|
|
|
29e444 |
@@ -201,7 +201,7 @@ CFLAGS-pt-system.c = -fexceptions
|
|
|
29e444 |
|
|
|
29e444 |
|
|
|
29e444 |
tests = tst-typesizes \
|
|
|
29e444 |
- tst-attr1 tst-attr2 tst-attr3 \
|
|
|
29e444 |
+ tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
|
|
|
29e444 |
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
|
|
|
29e444 |
tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
|
|
|
29e444 |
tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
|
|
|
29e444 |
@@ -276,6 +276,13 @@ gen-as-const-headers = pthread-errnos.sy
|
|
|
29e444 |
|
|
|
29e444 |
LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
|
|
|
29e444 |
|
|
|
29e444 |
+# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack
|
|
|
29e444 |
+# from resizing the input size to avoid the 64K aliasing conflict on Intel
|
|
|
29e444 |
+# processors.
|
|
|
29e444 |
+DEFAULT_STACKSIZE=1052672
|
|
|
29e444 |
+CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE)
|
|
|
29e444 |
+tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE)
|
|
|
29e444 |
+
|
|
|
29e444 |
include ../Makeconfig
|
|
|
29e444 |
|
|
|
29e444 |
ifeq ($(have-forced-unwind),yes)
|
|
|
29e444 |
diff -pruN glibc-2.17-c758a686/nptl/nptl-init.c glibc-2.17-c758a686.new/nptl/nptl-init.c
|
|
|
29e444 |
--- glibc-2.17-c758a686/nptl/nptl-init.c 2013-07-30 11:46:35.112902019 +0530
|
|
|
29e444 |
+++ glibc-2.17-c758a686.new/nptl/nptl-init.c 2013-07-30 11:46:44.601901689 +0530
|
|
|
29e444 |
@@ -35,6 +35,7 @@
|
|
|
29e444 |
#include <smp.h>
|
|
|
29e444 |
#include <lowlevellock.h>
|
|
|
29e444 |
#include <kernel-features.h>
|
|
|
29e444 |
+#include <libc-internal.h>
|
|
|
29e444 |
|
|
|
29e444 |
|
|
|
29e444 |
/* Size and alignment of static TLS block. */
|
|
|
29e444 |
@@ -276,8 +277,28 @@ extern void **__libc_dl_error_tsd (void)
|
|
|
29e444 |
/* This can be set by the debugger before initialization is complete. */
|
|
|
29e444 |
static bool __nptl_initial_report_events __attribute_used__;
|
|
|
29e444 |
|
|
|
29e444 |
+/* Validate and set the default stacksize. */
|
|
|
29e444 |
+static void
|
|
|
29e444 |
+set_default_stacksize (size_t stacksize)
|
|
|
29e444 |
+{
|
|
|
29e444 |
+ if (stacksize < PTHREAD_STACK_MIN)
|
|
|
29e444 |
+ stacksize = PTHREAD_STACK_MIN;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ /* Make sure it meets the minimum size that allocate_stack
|
|
|
29e444 |
+ (allocatestack.c) will demand, which depends on the page size. */
|
|
|
29e444 |
+ const uintptr_t pagesz = GLRO(dl_pagesize);
|
|
|
29e444 |
+ const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (stacksize < minstack)
|
|
|
29e444 |
+ stacksize = minstack;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ /* Round the resource limit up to page size. */
|
|
|
29e444 |
+ stacksize = ALIGN_UP (stacksize, pagesz);
|
|
|
29e444 |
+ __default_pthread_attr.stacksize = stacksize;
|
|
|
29e444 |
+}
|
|
|
29e444 |
+
|
|
|
29e444 |
void
|
|
|
29e444 |
-__pthread_initialize_minimal_internal (void)
|
|
|
29e444 |
+__pthread_initialize_minimal_internal (int argc, char **argv, char **envp)
|
|
|
29e444 |
{
|
|
|
29e444 |
#ifndef SHARED
|
|
|
29e444 |
/* Unlike in the dynamically linked case the dynamic linker has not
|
|
|
29e444 |
@@ -401,29 +422,44 @@ __pthread_initialize_minimal_internal (v
|
|
|
29e444 |
|
|
|
29e444 |
__static_tls_size = roundup (__static_tls_size, static_tls_align);
|
|
|
29e444 |
|
|
|
29e444 |
- /* Determine the default allowed stack size. This is the size used
|
|
|
29e444 |
- in case the user does not specify one. */
|
|
|
29e444 |
- struct rlimit limit;
|
|
|
29e444 |
- if (__getrlimit (RLIMIT_STACK, &limit) != 0
|
|
|
29e444 |
- || limit.rlim_cur == RLIM_INFINITY)
|
|
|
29e444 |
- /* The system limit is not usable. Use an architecture-specific
|
|
|
29e444 |
- default. */
|
|
|
29e444 |
- limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
|
|
|
29e444 |
- else if (limit.rlim_cur < PTHREAD_STACK_MIN)
|
|
|
29e444 |
- /* The system limit is unusably small.
|
|
|
29e444 |
- Use the minimal size acceptable. */
|
|
|
29e444 |
- limit.rlim_cur = PTHREAD_STACK_MIN;
|
|
|
29e444 |
+ /* Initialize the environment. libc.so gets initialized after us due to a
|
|
|
29e444 |
+ circular dependency and hence __environ is not available otherwise. */
|
|
|
29e444 |
+ __environ = envp;
|
|
|
29e444 |
|
|
|
29e444 |
- /* Make sure it meets the minimum size that allocate_stack
|
|
|
29e444 |
- (allocatestack.c) will demand, which depends on the page size. */
|
|
|
29e444 |
- const uintptr_t pagesz = GLRO(dl_pagesize);
|
|
|
29e444 |
- const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
|
|
|
29e444 |
- if (limit.rlim_cur < minstack)
|
|
|
29e444 |
- limit.rlim_cur = minstack;
|
|
|
29e444 |
+#ifndef SHARED
|
|
|
29e444 |
+ __libc_init_secure ();
|
|
|
29e444 |
+#endif
|
|
|
29e444 |
|
|
|
29e444 |
- /* Round the resource limit up to page size. */
|
|
|
29e444 |
- limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
|
|
|
29e444 |
- __default_pthread_attr.stacksize = limit.rlim_cur;
|
|
|
29e444 |
+ /* Get the default stack size from the environment variable if it is set and
|
|
|
29e444 |
+ is valid. */
|
|
|
29e444 |
+ size_t stacksize = 0;
|
|
|
29e444 |
+ char *envval = __libc_secure_getenv ("GLIBC_PTHREAD_STACKSIZE");
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (__builtin_expect (envval != NULL && envval[0] != '\0', 0))
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ char *env_conv = envval;
|
|
|
29e444 |
+ size_t ret = strtoul (envval, &env_conv, 0);
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (*env_conv == '\0' && env_conv != envval)
|
|
|
29e444 |
+ stacksize = ret;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (stacksize == 0)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ /* Determine the default allowed stack size. */
|
|
|
29e444 |
+ struct rlimit limit;
|
|
|
29e444 |
+ if (__getrlimit (RLIMIT_STACK, &limit) != 0
|
|
|
29e444 |
+ || limit.rlim_cur == RLIM_INFINITY)
|
|
|
29e444 |
+ /* The system limit is not usable. Use an architecture-specific
|
|
|
29e444 |
+ default. */
|
|
|
29e444 |
+ stacksize = ARCH_STACK_DEFAULT_SIZE;
|
|
|
29e444 |
+ else
|
|
|
29e444 |
+ stacksize = limit.rlim_cur;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+
|
|
|
29e444 |
+ /* Finally, set the default stack size. This size is used when the user does
|
|
|
29e444 |
+ not specify a stack size during thread creation. */
|
|
|
29e444 |
+ set_default_stacksize (stacksize);
|
|
|
29e444 |
__default_pthread_attr.guardsize = GLRO (dl_pagesize);
|
|
|
29e444 |
|
|
|
29e444 |
#ifdef SHARED
|
|
|
29e444 |
diff -pruN glibc-2.17-c758a686/nptl/tst-default-attr.c glibc-2.17-c758a686.new/nptl/tst-default-attr.c
|
|
|
29e444 |
--- glibc-2.17-c758a686/nptl/tst-default-attr.c 1970-01-01 05:30:00.000000000 +0530
|
|
|
29e444 |
+++ glibc-2.17-c758a686.new/nptl/tst-default-attr.c 2013-07-30 11:46:44.601901689 +0530
|
|
|
29e444 |
@@ -0,0 +1,109 @@
|
|
|
29e444 |
+/* Verify that default stack size gets set correctly from the environment
|
|
|
29e444 |
+ variable.
|
|
|
29e444 |
+
|
|
|
29e444 |
+ Copyright (C) 2013 Free Software Foundation, Inc.
|
|
|
29e444 |
+ This file is part of the GNU C Library.
|
|
|
29e444 |
+
|
|
|
29e444 |
+ The GNU C Library is free software; you can redistribute it and/or
|
|
|
29e444 |
+ modify it under the terms of the GNU Lesser General Public
|
|
|
29e444 |
+ License as published by the Free Software Foundation; either
|
|
|
29e444 |
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
29e444 |
+
|
|
|
29e444 |
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
|
29e444 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
29e444 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
29e444 |
+ Lesser General Public License for more details.
|
|
|
29e444 |
+
|
|
|
29e444 |
+ You should have received a copy of the GNU Lesser General Public
|
|
|
29e444 |
+ License along with the GNU C Library; if not, see
|
|
|
29e444 |
+ <http://www.gnu.org/licenses/>. */
|
|
|
29e444 |
+
|
|
|
29e444 |
+#include <pthread.h>
|
|
|
29e444 |
+#include <stdio.h>
|
|
|
29e444 |
+#include <stdint.h>
|
|
|
29e444 |
+#include <string.h>
|
|
|
29e444 |
+#include <unistd.h>
|
|
|
29e444 |
+#include <errno.h>
|
|
|
29e444 |
+
|
|
|
29e444 |
+#define RETURN_IF_FAIL(f, ...) \
|
|
|
29e444 |
+ ({ \
|
|
|
29e444 |
+ int ret = f (__VA_ARGS__); \
|
|
|
29e444 |
+ if (ret != 0) \
|
|
|
29e444 |
+ { \
|
|
|
29e444 |
+ printf ("%s:%d: %s returned %d (errno = %d)\n", __FILE__, __LINE__, \
|
|
|
29e444 |
+ #f, ret, errno); \
|
|
|
29e444 |
+ return ret; \
|
|
|
29e444 |
+ } \
|
|
|
29e444 |
+ })
|
|
|
29e444 |
+
|
|
|
29e444 |
+/* DEFAULT_STACKSIZE macro is defined in the Makefile. */
|
|
|
29e444 |
+static size_t stacksize = DEFAULT_STACKSIZE;
|
|
|
29e444 |
+
|
|
|
29e444 |
+static int
|
|
|
29e444 |
+verify_stacksize_result (pthread_attr_t *attr)
|
|
|
29e444 |
+{
|
|
|
29e444 |
+ size_t stack;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack);
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (stacksize != stack)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack);
|
|
|
29e444 |
+ return 1;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+
|
|
|
29e444 |
+ return 0;
|
|
|
29e444 |
+}
|
|
|
29e444 |
+
|
|
|
29e444 |
+static void *
|
|
|
29e444 |
+thr (void *unused __attribute__ ((unused)))
|
|
|
29e444 |
+{
|
|
|
29e444 |
+ pthread_attr_t attr;
|
|
|
29e444 |
+ int ret;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ memset (&attr, 0xab, sizeof attr);
|
|
|
29e444 |
+ /* To verify that the attributes actually got applied. */
|
|
|
29e444 |
+ if ((ret = pthread_getattr_np (pthread_self (), &attr)) != 0)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ printf ("pthread_getattr_np failed: %s\n", strerror (ret));
|
|
|
29e444 |
+ goto out;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+
|
|
|
29e444 |
+ ret = verify_stacksize_result (&attr);
|
|
|
29e444 |
+
|
|
|
29e444 |
+out:
|
|
|
29e444 |
+ return (void *) (uintptr_t) ret;
|
|
|
29e444 |
+}
|
|
|
29e444 |
+
|
|
|
29e444 |
+static int
|
|
|
29e444 |
+run_threads (void)
|
|
|
29e444 |
+{
|
|
|
29e444 |
+ pthread_t t;
|
|
|
29e444 |
+ void *tret = NULL;
|
|
|
29e444 |
+
|
|
|
29e444 |
+ /* Run twice to ensure that the attributes do not get overwritten in the
|
|
|
29e444 |
+ first run somehow. */
|
|
|
29e444 |
+ for (int i = 0; i < 2; i++)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ RETURN_IF_FAIL (pthread_create, &t, NULL, thr, NULL);
|
|
|
29e444 |
+ RETURN_IF_FAIL (pthread_join, t, &tret);
|
|
|
29e444 |
+
|
|
|
29e444 |
+ if (tret != NULL)
|
|
|
29e444 |
+ {
|
|
|
29e444 |
+ puts ("Thread failed");
|
|
|
29e444 |
+ return 1;
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+ }
|
|
|
29e444 |
+
|
|
|
29e444 |
+ return 0;
|
|
|
29e444 |
+}
|
|
|
29e444 |
+
|
|
|
29e444 |
+static int
|
|
|
29e444 |
+do_test (void)
|
|
|
29e444 |
+{
|
|
|
29e444 |
+ RETURN_IF_FAIL (run_threads);
|
|
|
29e444 |
+ return 0;
|
|
|
29e444 |
+}
|
|
|
29e444 |
+
|
|
|
29e444 |
+#define TEST_FUNCTION do_test ()
|
|
|
29e444 |
+#include "../test-skeleton.c"
|