aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog12
-rw-r--r--nptl/allocatestack.c78
-rw-r--r--nptl/init.c4
-rw-r--r--nptl/pthreadP.h2
-rw-r--r--nptl/sysdeps/pthread/pthread-functions.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c8
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 ();
+}