mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
* allocatestack.c (__free_stacks): Renamed from free_stacks.
(__free_stack_cache): Removed. Change callers to call __free_stacks. * init.c (nptl_freeres): New function. (pthread_functions): Initialize ptr_freeres to nptl_freeres. * pthreadP.h: Don't declare __free_stack_cache. Declare __free_stacks. * sysdeps/pthread/unwind-forcedunwind.c (libgcc_s_handle): New variable. (pthread_cancel_init): Depend in libgcc_s_handle for decision to load DSO. Assign last. (__unwind_freeres): New function. * allocatestack.c (__reclaim_stacks): Reset in_flight_stack later for better debugging. No need to use stack_list_add here.
This commit is contained in:
@ -1,3 +1,19 @@
|
|||||||
|
2009-01-29 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* allocatestack.c (__free_stacks): Renamed from free_stacks.
|
||||||
|
(__free_stack_cache): Removed. Change callers to call __free_stacks.
|
||||||
|
* init.c (nptl_freeres): New function.
|
||||||
|
(pthread_functions): Initialize ptr_freeres to nptl_freeres.
|
||||||
|
* pthreadP.h: Don't declare __free_stack_cache. Declare __free_stacks.
|
||||||
|
* sysdeps/pthread/unwind-forcedunwind.c (libgcc_s_handle): New
|
||||||
|
variable.
|
||||||
|
(pthread_cancel_init): Depend in libgcc_s_handle for decision to
|
||||||
|
load DSO. Assign last.
|
||||||
|
(__unwind_freeres): New function.
|
||||||
|
|
||||||
|
* allocatestack.c (__reclaim_stacks): Reset in_flight_stack later
|
||||||
|
for better debugging. No need to use stack_list_add here.
|
||||||
|
|
||||||
2009-01-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
2009-01-14 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sh/lowlevellock.S
|
* sysdeps/unix/sysv/linux/sh/lowlevellock.S
|
||||||
|
@ -248,8 +248,8 @@ get_cached_stack (size_t *sizep, void **memp)
|
|||||||
|
|
||||||
|
|
||||||
/* Free stacks until cache size is lower than LIMIT. */
|
/* Free stacks until cache size is lower than LIMIT. */
|
||||||
static void
|
void
|
||||||
free_stacks (size_t limit)
|
__free_stacks (size_t limit)
|
||||||
{
|
{
|
||||||
/* We reduce the size of the cache. Remove the last entries until
|
/* We reduce the size of the cache. Remove the last entries until
|
||||||
the size is below the limit. */
|
the size is below the limit. */
|
||||||
@ -299,15 +299,7 @@ queue_stack (struct pthread *stack)
|
|||||||
|
|
||||||
stack_cache_actsize += stack->stackblock_size;
|
stack_cache_actsize += stack->stackblock_size;
|
||||||
if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
|
if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
|
||||||
free_stacks (stack_cache_maxsize);
|
__free_stacks (stack_cache_maxsize);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This function is called indirectly from the freeres code in libc. */
|
|
||||||
void
|
|
||||||
__free_stack_cache (void)
|
|
||||||
{
|
|
||||||
free_stacks (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -849,8 +841,6 @@ __reclaim_stacks (void)
|
|||||||
elem->next->prev = elem->prev;
|
elem->next->prev = elem->prev;
|
||||||
elem->prev->next = elem->next;
|
elem->prev->next = elem->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
in_flight_stack = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark all stacks except the still running one as free. */
|
/* Mark all stacks except the still running one as free. */
|
||||||
@ -913,11 +903,13 @@ __reclaim_stacks (void)
|
|||||||
if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0))
|
if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0))
|
||||||
list_add (&self->list, &__stack_user);
|
list_add (&self->list, &__stack_user);
|
||||||
else
|
else
|
||||||
stack_list_add (&self->list, &stack_used);
|
list_add (&self->list, &stack_used);
|
||||||
|
|
||||||
/* There is one thread running. */
|
/* There is one thread running. */
|
||||||
__nptl_nthreads = 1;
|
__nptl_nthreads = 1;
|
||||||
|
|
||||||
|
in_flight_stack = 0;
|
||||||
|
|
||||||
/* Initialize the lock. */
|
/* Initialize the lock. */
|
||||||
stack_cache_lock = LLL_LOCK_INITIALIZER;
|
stack_cache_lock = LLL_LOCK_INITIALIZER;
|
||||||
}
|
}
|
||||||
|
16
nptl/init.c
16
nptl/init.c
@ -67,6 +67,8 @@ static const char nptl_version[] __attribute_used__ = VERSION;
|
|||||||
extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
|
extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void nptl_freeres (void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
static const struct pthread_functions pthread_functions =
|
static const struct pthread_functions pthread_functions =
|
||||||
@ -128,7 +130,7 @@ static const struct pthread_functions pthread_functions =
|
|||||||
.ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
|
.ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
|
||||||
.ptr__nptl_setxid = __nptl_setxid,
|
.ptr__nptl_setxid = __nptl_setxid,
|
||||||
/* For now only the stack cache needs to be freed. */
|
/* For now only the stack cache needs to be freed. */
|
||||||
.ptr_freeres = __free_stack_cache
|
.ptr_freeres = nptl_freeres
|
||||||
};
|
};
|
||||||
# define ptr_pthread_functions &pthread_functions
|
# define ptr_pthread_functions &pthread_functions
|
||||||
#else
|
#else
|
||||||
@ -136,6 +138,18 @@ static const struct pthread_functions pthread_functions =
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is called indirectly from the freeres code in libc. */
|
||||||
|
static void
|
||||||
|
__libc_freeres_fn_section
|
||||||
|
nptl_freeres (void)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
__unwind_freeres ();
|
||||||
|
#endif
|
||||||
|
__free_stacks (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* For asynchronous cancellation we use a signal. This is the handler. */
|
/* For asynchronous cancellation we use a signal. This is the handler. */
|
||||||
static void
|
static void
|
||||||
sigcancel_handler (int sig, siginfo_t *si, void *ctx)
|
sigcancel_handler (int sig, siginfo_t *si, void *ctx)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
|
/* Copyright (C) 2002-2007, 2009 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
@ -247,6 +247,7 @@ hidden_proto (__pthread_register_cancel)
|
|||||||
hidden_proto (__pthread_unregister_cancel)
|
hidden_proto (__pthread_unregister_cancel)
|
||||||
# ifdef SHARED
|
# ifdef SHARED
|
||||||
extern void attribute_hidden pthread_cancel_init (void);
|
extern void attribute_hidden pthread_cancel_init (void);
|
||||||
|
extern void __unwind_freeres (void);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -564,7 +565,7 @@ extern void __nptl_deallocate_tsd (void) attribute_hidden;
|
|||||||
|
|
||||||
extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
|
extern int __nptl_setxid (struct xid_command *cmdp) attribute_hidden;
|
||||||
|
|
||||||
extern void __free_stack_cache (void) attribute_hidden;
|
extern void __free_stacks (size_t limit) attribute_hidden;
|
||||||
|
|
||||||
extern void __wait_lookup_done (void) attribute_hidden;
|
extern void __wait_lookup_done (void) attribute_hidden;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
|
/* Copyright (C) 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
Contributed by Jakub Jelinek <jakub@redhat.com>.
|
||||||
|
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include <unwind.h>
|
#include <unwind.h>
|
||||||
#include <pthreadP.h>
|
#include <pthreadP.h>
|
||||||
|
|
||||||
|
static void *libgcc_s_handle;
|
||||||
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
|
static void (*libgcc_s_resume) (struct _Unwind_Exception *exc);
|
||||||
static _Unwind_Reason_Code (*libgcc_s_personality)
|
static _Unwind_Reason_Code (*libgcc_s_personality)
|
||||||
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
|
(int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
|
||||||
@ -37,7 +38,7 @@ pthread_cancel_init (void)
|
|||||||
void *resume, *personality, *forcedunwind, *getcfa;
|
void *resume, *personality, *forcedunwind, *getcfa;
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
|
if (__builtin_expect (libgcc_s_handle != NULL, 1))
|
||||||
{
|
{
|
||||||
/* Force gcc to reload all values. */
|
/* Force gcc to reload all values. */
|
||||||
asm volatile ("" ::: "memory");
|
asm volatile ("" ::: "memory");
|
||||||
@ -61,11 +62,24 @@ pthread_cancel_init (void)
|
|||||||
libgcc_s_resume = resume;
|
libgcc_s_resume = resume;
|
||||||
libgcc_s_personality = personality;
|
libgcc_s_personality = personality;
|
||||||
libgcc_s_forcedunwind = forcedunwind;
|
libgcc_s_forcedunwind = forcedunwind;
|
||||||
/* Make sure libgcc_s_getcfa is written last. Otherwise,
|
libgcc_s_getcfa = getcfa;
|
||||||
|
/* Make sure libgcc_s_handle is written last. Otherwise,
|
||||||
pthread_cancel_init might return early even when the pointer the
|
pthread_cancel_init might return early even when the pointer the
|
||||||
caller is interested in is not initialized yet. */
|
caller is interested in is not initialized yet. */
|
||||||
atomic_write_barrier ();
|
atomic_write_barrier ();
|
||||||
libgcc_s_getcfa = getcfa;
|
libgcc_s_handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__libc_freeres_fn_section
|
||||||
|
__unwind_freeres (void)
|
||||||
|
{
|
||||||
|
void *handle = libgcc_s_handle;
|
||||||
|
if (handle != NULL)
|
||||||
|
{
|
||||||
|
libgcc_s_handle = NULL;
|
||||||
|
__libc_dlclose (handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Reference in New Issue
Block a user