about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-11-23 14:47:31 +0100
committerFlorian Weimer <fweimer@redhat.com>2017-11-23 14:47:31 +0100
commit0a947e061d47c9710838f210506215bd9533324b (patch)
tree7b794c6778f0b904909e87a560696799bbcd4e7d
parent67f36c7922fe5053549ec9aa7f60ed2c5c2d65b4 (diff)
downloadglibc-0a947e061d47c9710838f210506215bd9533324b.tar.gz
glibc-0a947e061d47c9710838f210506215bd9533324b.tar.xz
glibc-0a947e061d47c9710838f210506215bd9533324b.zip
malloc: Call tcache destructor in arena_thread_freeres
It does not make sense to register separate cleanup functions for arena
and tcache since they're always going to be called together.  Call the
tcache cleanup function from within arena_thread_freeres since it at
least makes the order of those cleanups clear in the code.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
-rw-r--r--ChangeLog8
-rw-r--r--malloc/arena.c5
-rw-r--r--malloc/malloc.c23
3 files changed, 29 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index d9222a58d2..9a9efa54d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2017-11-23  Florian Weimer  <fweimer@redhat.com>
 
+	* malloc/malloc.c (tcache_thread_shutdown): Rename from
+	tcache_thread_freeres.  Define for USE_TCACHE and !USE_TCACHE
+	alike.  Remove freeres marker.
+	* malloc/arena.c (arena_thread_freeres): Call
+	tcache_thread_shutdown.
+
+2017-11-23  Florian Weimer  <fweimer@redhat.com>
+
 	[BZ #22459]
 	Export nscd hash function as __nss_hash.
 	* include/nss.h (__nss_hash): Declare.
diff --git a/malloc/arena.c b/malloc/arena.c
index 85b985e193..4d27e17c46 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -944,6 +944,11 @@ arena_get_retry (mstate ar_ptr, size_t bytes)
 static void __attribute__ ((section ("__libc_thread_freeres_fn")))
 arena_thread_freeres (void)
 {
+  /* Shut down the thread cache first.  This could deallocate data for
+     the thread arena, so do this before we put the arena on the free
+     list.  */
+  tcache_thread_shutdown ();
+
   mstate a = thread_arena;
   thread_arena = NULL;
 
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 2999ac4d2f..79f0e9eac7 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1869,6 +1869,9 @@ void *weak_variable (*__memalign_hook)
   = memalign_hook_ini;
 void weak_variable (*__after_morecore_hook) (void) = NULL;
 
+/* This function is called from the arena shutdown hook, to free the
+   thread cache (if it exists).  */
+static void tcache_thread_shutdown (void);
 
 /* ------------------ Testing support ----------------------------------*/
 
@@ -2938,8 +2941,8 @@ tcache_get (size_t tc_idx)
   return (void *) e;
 }
 
-static void __attribute__ ((section ("__libc_thread_freeres_fn")))
-tcache_thread_freeres (void)
+static void
+tcache_thread_shutdown (void)
 {
   int i;
   tcache_perthread_struct *tcache_tmp = tcache;
@@ -2965,7 +2968,6 @@ tcache_thread_freeres (void)
 
   __libc_free (tcache_tmp);
 }
-text_set_element (__libc_thread_subfreeres, tcache_thread_freeres);
 
 static void
 tcache_init(void)
@@ -3002,13 +3004,20 @@ tcache_init(void)
 
 }
 
-#define MAYBE_INIT_TCACHE() \
+# define MAYBE_INIT_TCACHE() \
   if (__glibc_unlikely (tcache == NULL)) \
     tcache_init();
 
-#else
-#define MAYBE_INIT_TCACHE()
-#endif
+#else  /* !USE_TCACHE */
+# define MAYBE_INIT_TCACHE()
+
+static void
+tcache_thread_shutdown (void)
+{
+  /* Nothing to do if there is no thread cache.  */
+}
+
+#endif /* !USE_TCACHE  */
 
 void *
 __libc_malloc (size_t bytes)