about summary refs log tree commit diff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog16
-rw-r--r--nptl/allocatestack.c20
-rw-r--r--nptl/init.c16
-rw-r--r--nptl/pthreadP.h5
-rw-r--r--nptl/sysdeps/pthread/unwind-forcedunwind.c22
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  <drepper@redhat.com>
+
+	* 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  <kkojima@rr.iij4u.or.jp>
 
 	* 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 <drepper@redhat.com>, 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 <jakub@redhat.com>.
 
@@ -22,6 +22,7 @@
 #include <unwind.h>
 #include <pthreadP.h>
 
+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