mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-07 06:43:00 +03:00
Revert GLIBC_PTHREAD_DEFAULT_STACKSIZE changes.
This reverts the change that allows the POSIX Thread default stack size to be changed by the environment variable GLIBC_PTHREAD_DEFAULT_STACKSIZE. It has been requested that more discussion happen before this change goes into 2.18.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2013-03-01 Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
* csu/libc-start.c (__pthread_initialize_minimal): Revert last change.
|
||||||
|
* csu/libc-tls.c (__pthread_initialize_minimal): Likewise.
|
||||||
|
|
||||||
2013-03-01 Siddhesh Poyarekar <siddhesh@redhat.com>
|
2013-03-01 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
* NEWS: Mention libm performance improvements and non-x86 PI
|
* NEWS: Mention libm performance improvements and non-x86 PI
|
||||||
|
4
NEWS
4
NEWS
@@ -17,10 +17,6 @@ Version 2.18
|
|||||||
and program exit. This needs compiler support for offloading C++11
|
and program exit. This needs compiler support for offloading C++11
|
||||||
destructor calls to glibc.
|
destructor calls to glibc.
|
||||||
|
|
||||||
* Add support for setting thread stack sizes from the program environment,
|
|
||||||
independently of the process stack size using the
|
|
||||||
GLIBC_PTHREAD_DEFAULT_STACKSIZE environment variable.
|
|
||||||
|
|
||||||
* Improved worst case performance of libm functions with double inputs and
|
* Improved worst case performance of libm functions with double inputs and
|
||||||
output.
|
output.
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ extern int __libc_multiple_libcs;
|
|||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#ifndef SHARED
|
#ifndef SHARED
|
||||||
# include <dl-osinfo.h>
|
# include <dl-osinfo.h>
|
||||||
extern void __pthread_initialize_minimal (int, char **, char **);
|
extern void __pthread_initialize_minimal (void);
|
||||||
# ifndef THREAD_SET_STACK_GUARD
|
# ifndef THREAD_SET_STACK_GUARD
|
||||||
/* Only exported for architectures that don't store the stack guard canary
|
/* Only exported for architectures that don't store the stack guard canary
|
||||||
in thread local area. */
|
in thread local area. */
|
||||||
@@ -167,7 +167,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
|||||||
/* Initialize the thread library at least a bit since the libgcc
|
/* Initialize the thread library at least a bit since the libgcc
|
||||||
functions are using thread functions if these are available and
|
functions are using thread functions if these are available and
|
||||||
we need to setup errno. */
|
we need to setup errno. */
|
||||||
__pthread_initialize_minimal (argc, argv, __environ);
|
__pthread_initialize_minimal ();
|
||||||
|
|
||||||
/* Set up the stack checker's canary. */
|
/* Set up the stack checker's canary. */
|
||||||
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
|
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
|
||||||
|
@@ -243,7 +243,7 @@ _dl_tls_setup (void)
|
|||||||
not used. */
|
not used. */
|
||||||
void
|
void
|
||||||
__attribute__ ((weak))
|
__attribute__ ((weak))
|
||||||
__pthread_initialize_minimal (int argc, char **argv, char **envp)
|
__pthread_initialize_minimal (void)
|
||||||
{
|
{
|
||||||
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
|
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,11 @@
|
|||||||
|
2013-03-01 Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
* Makefile (tests): Revert last change.
|
||||||
|
(tst-pthread-stack-env-ENV): Likewise.
|
||||||
|
* nptl-init.c (set_default_stacksize): Likewise.
|
||||||
|
(__pthread_initialize_minimal_internal): Likewise.
|
||||||
|
* tst-pthread-stack-env.c: Likewise.
|
||||||
|
|
||||||
2013-03-01 Siddhesh Poyarekar <siddhesh@redhat.com>
|
2013-03-01 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
* tst-oddstacklimit.c: Include stdlib.h.
|
* tst-oddstacklimit.c: Include stdlib.h.
|
||||||
|
@@ -251,8 +251,7 @@ tests = tst-typesizes \
|
|||||||
tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
|
tst-exec1 tst-exec2 tst-exec3 tst-exec4 \
|
||||||
tst-exit1 tst-exit2 tst-exit3 \
|
tst-exit1 tst-exit2 tst-exit3 \
|
||||||
tst-stdio1 tst-stdio2 \
|
tst-stdio1 tst-stdio2 \
|
||||||
tst-stack1 tst-stack2 tst-stack3 \
|
tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \
|
||||||
tst-pthread-getattr tst-pthread-stack-env \
|
|
||||||
tst-unload \
|
tst-unload \
|
||||||
tst-dlsym1 \
|
tst-dlsym1 \
|
||||||
tst-sysconf \
|
tst-sysconf \
|
||||||
@@ -442,8 +441,6 @@ tst-cancel7-ARGS = --command "exec $(host-test-program-cmd)"
|
|||||||
tst-cancelx7-ARGS = $(tst-cancel7-ARGS)
|
tst-cancelx7-ARGS = $(tst-cancel7-ARGS)
|
||||||
tst-umask1-ARGS = $(objpfx)tst-umask1.temp
|
tst-umask1-ARGS = $(objpfx)tst-umask1.temp
|
||||||
|
|
||||||
tst-pthread-stack-env-ENV = GLIBC_PTHREAD_DEFAULT_STACKSIZE=1048576
|
|
||||||
|
|
||||||
$(objpfx)tst-atfork2: $(libdl) $(shared-thread-library)
|
$(objpfx)tst-atfork2: $(libdl) $(shared-thread-library)
|
||||||
LDFLAGS-tst-atfork2 = -rdynamic
|
LDFLAGS-tst-atfork2 = -rdynamic
|
||||||
tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
|
tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
|
||||||
|
@@ -276,26 +276,8 @@ extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
|
|||||||
/* This can be set by the debugger before initialization is complete. */
|
/* This can be set by the debugger before initialization is complete. */
|
||||||
static bool __nptl_initial_report_events __attribute_used__;
|
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
|
void
|
||||||
__pthread_initialize_minimal_internal (int argc, char **argv, char **envp)
|
__pthread_initialize_minimal_internal (void)
|
||||||
{
|
{
|
||||||
#ifndef SHARED
|
#ifndef SHARED
|
||||||
/* Unlike in the dynamically linked case the dynamic linker has not
|
/* Unlike in the dynamically linked case the dynamic linker has not
|
||||||
@@ -419,41 +401,29 @@ __pthread_initialize_minimal_internal (int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
__static_tls_size = roundup (__static_tls_size, static_tls_align);
|
__static_tls_size = roundup (__static_tls_size, static_tls_align);
|
||||||
|
|
||||||
/* Initialize the environment. libc.so gets initialized after us due to a
|
/* Determine the default allowed stack size. This is the size used
|
||||||
circular dependency and hence __environ is not available otherwise. */
|
in case the user does not specify one. */
|
||||||
__environ = envp;
|
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;
|
||||||
|
|
||||||
#ifndef SHARED
|
/* Make sure it meets the minimum size that allocate_stack
|
||||||
__libc_init_secure ();
|
(allocatestack.c) will demand, which depends on the page size. */
|
||||||
#endif
|
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;
|
||||||
|
|
||||||
size_t stacksize = 0;
|
/* Round the resource limit up to page size. */
|
||||||
char *envval = __libc_secure_getenv ("GLIBC_PTHREAD_DEFAULT_STACKSIZE");
|
limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
|
||||||
|
__default_stacksize = limit.rlim_cur;
|
||||||
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
|
#ifdef SHARED
|
||||||
/* Transfer the old value from the dynamic linker's internal location. */
|
/* Transfer the old value from the dynamic linker's internal location. */
|
||||||
|
@@ -1,77 +0,0 @@
|
|||||||
/* Verify that pthreads uses the default thread stack size set with the
|
|
||||||
GLIBC_PTHREAD_DEFAULT_STACKSIZE environment variable.
|
|
||||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with the GNU C Library; if not, see
|
|
||||||
<http://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* It is possible that the default stack size somehow ends up being 1MB, thus
|
|
||||||
giving a false positive. The ideal way to test this would be to get the
|
|
||||||
current stacksize fork a process with the default stack size set to
|
|
||||||
something different to the current stack size and verify in the child
|
|
||||||
process that the environment variable worked. */
|
|
||||||
#define STACKSIZE 1024 * 1024L
|
|
||||||
|
|
||||||
void *
|
|
||||||
thr (void *u)
|
|
||||||
{
|
|
||||||
size_t stacksize, guardsize;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pthread_getattr_np (pthread_self (), &attr);
|
|
||||||
|
|
||||||
pthread_attr_getstacksize (&attr, &stacksize);
|
|
||||||
pthread_attr_getguardsize (&attr, &guardsize);
|
|
||||||
|
|
||||||
/* FIXME once guardsize is excluded from stacksize. */
|
|
||||||
if (stacksize - guardsize != STACKSIZE)
|
|
||||||
{
|
|
||||||
printf ("Stack size is %zu, should be %zu\n", stacksize - guardsize,
|
|
||||||
STACKSIZE);
|
|
||||||
return (void *) 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
do_test (int argc, char **argv)
|
|
||||||
{
|
|
||||||
pthread_t t;
|
|
||||||
void *thr_ret;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ((ret = pthread_create (&t, NULL, thr, NULL)) != 0)
|
|
||||||
{
|
|
||||||
printf ("thread create failed: %s\n", strerror (ret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = pthread_join (t, &thr_ret)) != 0)
|
|
||||||
{
|
|
||||||
printf ("join failed: %s\n", strerror (ret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thr_ret != NULL && thr_ret != PTHREAD_CANCELED)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "../test-skeleton.c"
|
|
Reference in New Issue
Block a user