* allocatestack.c (queue_stack): Move freeing of surplus stacks to...
authorUlrich Drepper <drepper@redhat.com>
Wed, 23 Aug 2006 17:47:19 +0000 (17:47 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 23 Aug 2006 17:47:19 +0000 (17:47 +0000)
(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.

nptl/ChangeLog
nptl/allocatestack.c
nptl/init.c
nptl/pthreadP.h
nptl/sysdeps/pthread/pthread-functions.h
nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c

index aacea77..7ed7b38 100644 (file)
@@ -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]
index 4a1cd18..c05cd47 100644 (file)
@@ -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);
 }
 
 
index 7cfe803..1444115 100644 (file)
@@ -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
index 503e99b..f9634ab 100644 (file)
@@ -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
index d75bbbb..74d2400 100644 (file)
@@ -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.  */
index 4e60596..7c21d88 100644 (file)
@@ -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 ();
+}