about summary refs log tree commit diff
path: root/nptl/allocatestack.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-08-23 17:47:19 +0000
committerUlrich Drepper <drepper@redhat.com>2006-08-23 17:47:19 +0000
commitba408f846541f7279ef12858545abac1c26719e7 (patch)
treeee69064e7ad1e2309448d91f2125988debe2073c /nptl/allocatestack.c
parent9a464a6eff6a5a88c3fb68e8f4eabeaccd9f10dd (diff)
downloadglibc-ba408f846541f7279ef12858545abac1c26719e7.tar.gz
glibc-ba408f846541f7279ef12858545abac1c26719e7.tar.xz
glibc-ba408f846541f7279ef12858545abac1c26719e7.zip
* 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.
Diffstat (limited to 'nptl/allocatestack.c')
-rw-r--r--nptl/allocatestack.c78
1 files changed, 46 insertions, 32 deletions
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);
 }