From cca50323b6a80283886c5fb6e2cff25f6c2d006b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 29 Jan 2009 20:38:04 +0000 Subject: [PATCH] * 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. --- nptl/ChangeLog | 16 ++++++++++++++++ nptl/allocatestack.c | 20 ++++++-------------- nptl/init.c | 16 +++++++++++++++- nptl/pthreadP.h | 5 +++-- nptl/sysdeps/pthread/unwind-forcedunwind.c | 22 ++++++++++++++++++---- 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 4fb05b2feb..664e2e14f9 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,19 @@ +2009-01-29 Ulrich Drepper + + * 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 * sysdeps/unix/sysv/linux/sh/lowlevellock.S diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index ce05770e56..67ea0c68f8 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -248,8 +248,8 @@ get_cached_stack (size_t *sizep, void **memp) /* Free stacks until cache size is lower than LIMIT. */ -static void -free_stacks (size_t limit) +void +__free_stacks (size_t limit) { /* We reduce the size of the cache. Remove the last entries until the size is below the limit. */ @@ -299,15 +299,7 @@ queue_stack (struct pthread *stack) stack_cache_actsize += stack->stackblock_size; if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0)) - free_stacks (stack_cache_maxsize); -} - - -/* This function is called indirectly from the freeres code in libc. */ -void -__free_stack_cache (void) -{ - free_stacks (0); + __free_stacks (stack_cache_maxsize); } @@ -849,8 +841,6 @@ __reclaim_stacks (void) elem->next->prev = elem->prev; elem->prev->next = elem->next; } - - in_flight_stack = 0; } /* 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)) list_add (&self->list, &__stack_user); else - stack_list_add (&self->list, &stack_used); + list_add (&self->list, &stack_used); /* There is one thread running. */ __nptl_nthreads = 1; + in_flight_stack = 0; + /* Initialize the lock. */ stack_cache_lock = LLL_LOCK_INITIALIZER; } diff --git a/nptl/init.c b/nptl/init.c index 7a6dec5935..d0f1fc3be7 100644 --- a/nptl/init.c +++ b/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); #endif +static void nptl_freeres (void); + #ifdef SHARED 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_setxid = __nptl_setxid, /* 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 #else @@ -136,6 +138,18 @@ static const struct pthread_functions pthread_functions = #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. */ static void sigcancel_handler (int sig, siginfo_t *si, void *ctx) diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 17b6492ad8..ed9fc625ba 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -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. Contributed by Ulrich Drepper , 2002. @@ -247,6 +247,7 @@ hidden_proto (__pthread_register_cancel) hidden_proto (__pthread_unregister_cancel) # ifdef SHARED extern void attribute_hidden pthread_cancel_init (void); +extern void __unwind_freeres (void); # 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 void __free_stack_cache (void) attribute_hidden; +extern void __free_stacks (size_t limit) attribute_hidden; extern void __wait_lookup_done (void) attribute_hidden; diff --git a/nptl/sysdeps/pthread/unwind-forcedunwind.c b/nptl/sysdeps/pthread/unwind-forcedunwind.c index 6792d719d3..63f359bd9d 100644 --- a/nptl/sysdeps/pthread/unwind-forcedunwind.c +++ b/nptl/sysdeps/pthread/unwind-forcedunwind.c @@ -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. Contributed by Jakub Jelinek . @@ -22,6 +22,7 @@ #include #include +static void *libgcc_s_handle; static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); static _Unwind_Reason_Code (*libgcc_s_personality) (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, @@ -37,7 +38,7 @@ pthread_cancel_init (void) void *resume, *personality, *forcedunwind, *getcfa; void *handle; - if (__builtin_expect (libgcc_s_getcfa != NULL, 1)) + if (__builtin_expect (libgcc_s_handle != NULL, 1)) { /* Force gcc to reload all values. */ asm volatile ("" ::: "memory"); @@ -61,11 +62,24 @@ pthread_cancel_init (void) libgcc_s_resume = resume; libgcc_s_personality = personality; 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 caller is interested in is not initialized yet. */ 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 -- 2.43.5