diff options
-rw-r--r-- | nptl/ChangeLog | 12 | ||||
-rw-r--r-- | nptl/allocatestack.c | 78 | ||||
-rw-r--r-- | nptl/init.c | 4 | ||||
-rw-r--r-- | nptl/pthreadP.h | 2 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/pthread-functions.h | 3 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c | 8 |
6 files changed, 72 insertions, 35 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index aacea77835..7ed7b38e11 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,15 @@ +2006-08-23 Ulrich Drepper <drepper@redhat.com> + + * allocatestack.c (queue_stack): Move freeing of surplus stacks to... + (free_stacks): ...here. + (__free_stack_cache): New function. + * pthreadP.h: Declare __free_stack_cache. + * sysdeps/pthread/pthread-functions.h (pthread_functions): Add + ptr_freeres. + * init.c (pthread_functions): Initialize ptr_freeres. + * sysdeps/unix/sysv/linux/libc_pthread_init.c (freeres_libptread): + New freeres function. + 2006-07-30 Joseph S. Myers <joseph@codesourcery.com> [BZ #3018] diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 4a1cd18481..c05cd47dff 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -211,6 +211,45 @@ get_cached_stack (size_t *sizep, void **memp) } +/* Free stacks until cache size is lower than LIMIT. */ +static void +free_stacks (size_t limit) +{ + /* We reduce the size of the cache. Remove the last entries until + the size is below the limit. */ + list_t *entry; + list_t *prev; + + /* Search from the end of the list. */ + list_for_each_prev_safe (entry, prev, &stack_cache) + { + struct pthread *curr; + + curr = list_entry (entry, struct pthread, list); + if (FREE_P (curr)) + { + /* Unlink the block. */ + list_del (entry); + + /* Account for the freed memory. */ + stack_cache_actsize -= curr->stackblock_size; + + /* Free the memory associated with the ELF TLS. */ + _dl_deallocate_tls (TLS_TPADJ (curr), false); + + /* Remove this block. This should never fail. If it does + something is really wrong. */ + if (munmap (curr->stackblock, curr->stackblock_size) != 0) + abort (); + + /* Maybe we have freed enough. */ + if (stack_cache_actsize <= limit) + break; + } + } +} + + /* Add a stack frame which is not used anymore to the stack. Must be called with the cache lock held. */ static inline void @@ -224,40 +263,15 @@ queue_stack (struct pthread *stack) stack_cache_actsize += stack->stackblock_size; if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0)) - { - /* We reduce the size of the cache. Remove the last entries - until the size is below the limit. */ - list_t *entry; - list_t *prev; - - /* Search from the end of the list. */ - list_for_each_prev_safe (entry, prev, &stack_cache) - { - struct pthread *curr; - - curr = list_entry (entry, struct pthread, list); - if (FREE_P (curr)) - { - /* Unlink the block. */ - list_del (entry); - - /* Account for the freed memory. */ - stack_cache_actsize -= curr->stackblock_size; - - /* Free the memory associated with the ELF TLS. */ - _dl_deallocate_tls (TLS_TPADJ (curr), false); + free_stacks (stack_cache_maxsize); +} - /* Remove this block. This should never fail. If it - does something is really wrong. */ - if (munmap (curr->stackblock, curr->stackblock_size) != 0) - abort (); - /* Maybe we have freed enough. */ - if (stack_cache_actsize <= stack_cache_maxsize) - break; - } - } - } +/* This function is called indirectly from the freeres code in libc. */ +void +__free_stack_cache (void) +{ + free_stacks (0); } diff --git a/nptl/init.c b/nptl/init.c index 7cfe803c42..14441153b8 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -136,7 +136,9 @@ static const struct pthread_functions pthread_functions = .ptr_nthreads = &__nptl_nthreads, .ptr___pthread_unwind = &__pthread_unwind, .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. */ + .ptr_freeres = __free_stack_cache }; # define ptr_pthread_functions &pthread_functions #else diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 503e99b2b4..f9634ab0ff 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -543,6 +543,8 @@ 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; + #ifdef SHARED # define PTHREAD_STATIC_FN_REQUIRE(name) #else diff --git a/nptl/sysdeps/pthread/pthread-functions.h b/nptl/sysdeps/pthread/pthread-functions.h index d75bbbb11e..74d24005c3 100644 --- a/nptl/sysdeps/pthread/pthread-functions.h +++ b/nptl/sysdeps/pthread/pthread-functions.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -95,6 +95,7 @@ struct pthread_functions __attribute ((noreturn)) __cleanup_fct_attribute; void (*ptr__nptl_deallocate_tsd) (void); int (*ptr__nptl_setxid) (struct xid_command *); + void (*ptr_freeres) (void); }; /* Variable in libc.so. */ diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c index 4e60596f7d..7c21d88ef3 100644 --- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c +++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -57,3 +57,9 @@ __libc_pthread_init (ptr, reclaim, functions) return &__libc_multiple_threads; #endif } + + +libc_freeres_fn (freeres_libptread) +{ + __libc_pthread_functions.ptr_freeres (); +} |