[PATCH v2 3/3] malloc: limit when to allow to free chunks to tcache

Cupertino Miranda cupertino.miranda@oracle.com
Fri Dec 6 14:09:21 GMT 2024


There are internal calls to _int_free that should not allow the chunks
to be taken by tcache.
This code introduces an argument to _int_free function to allow to
disambiguate when the call is being done in a context which should not
allow tcache to take the chunk, for example, when top chunk is adjusted.
---
 malloc/malloc-check.c |  2 +-
 malloc/malloc.c       | 18 +++++++++---------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
index 6ac71df5d5..db0f6e33b1 100644
--- a/malloc/malloc-check.c
+++ b/malloc/malloc-check.c
@@ -235,7 +235,7 @@ free_check (void *mem)
     {
       /* Mark the chunk as belonging to the library again.  */
       (void)tag_region (chunk2mem (p), memsize (p));
-      _int_free (&main_arena, p, 1);
+      _int_free (&main_arena, p, 1, 1);
       __libc_lock_unlock (main_arena.mutex);
     }
   __set_errno (err);
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 642cdffd23..05e5b3f230 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1090,7 +1090,7 @@ typedef struct malloc_chunk* mchunkptr;
 /* Internal routines.  */
 
 static void*  _int_malloc(mstate, size_t);
-static void _int_free (mstate, mchunkptr, int);
+static void _int_free (mstate, mchunkptr, int, int);
 static void _int_free_check (mstate, mchunkptr, INTERNAL_SIZE_T);
 static void _int_free_chunk (mstate, mchunkptr, INTERNAL_SIZE_T, int);
 static void _int_free_merge_chunk (mstate, mchunkptr, INTERNAL_SIZE_T);
@@ -2653,7 +2653,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
 			CHUNK_HDR_SZ | PREV_INUSE);
               set_foot (chunk_at_offset (old_top, old_size), CHUNK_HDR_SZ);
               set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA);
-              _int_free (av, old_top, 1);
+              _int_free (av, old_top, 1, 0);
             }
           else
             {
@@ -2919,7 +2919,7 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av)
                       /* If possible, release the rest. */
                       if (old_size >= MINSIZE)
                         {
-                          _int_free (av, old_top, 1);
+                          _int_free (av, old_top, 1, 0);
                         }
                     }
                 }
@@ -3693,7 +3693,7 @@ __libc_free (void *mem)
       (void)tag_region (chunk2mem (p), memsize (p));
 
       ar_ptr = arena_for_chunk (p);
-      _int_free (ar_ptr, p, 0);
+      _int_free (ar_ptr, p, 0, 1);
     }
 
   __set_errno (err);
@@ -3828,7 +3828,7 @@ __libc_realloc (void *oldmem, size_t bytes)
 	  size_t sz = memsize (oldp);
 	  memcpy (newp, oldmem, sz);
 	  (void) tag_region (chunk2mem (oldp), sz);
-          _int_free (ar_ptr, oldp, 0);
+          _int_free (ar_ptr, oldp, 0, 1);
         }
     }
 
@@ -4902,7 +4902,7 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
    fast path to free into tcache.  If the attempt not success, free the
    chunk to arena.  */
 static inline void
-_int_free (mstate av, mchunkptr p, int have_lock)
+_int_free (mstate av, mchunkptr p, int have_lock, int allow_tcache)
 {
   INTERNAL_SIZE_T size;        /* its size */
 
@@ -4911,7 +4911,7 @@ _int_free (mstate av, mchunkptr p, int have_lock)
   _int_free_check (av, p, size);
 
 #if USE_TCACHE
-  if (tcache_free (p, size))
+  if (allow_tcache && tcache_free (p, size))
     return;
 #endif
 
@@ -5270,7 +5270,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
 	      (void) tag_region (oldmem, sz);
 	      newmem = tag_new_usable (newmem);
 	      memcpy (newmem, oldmem, sz);
-	      _int_free (av, oldp, 1);
+	      _int_free (av, oldp, 1, 1);
 	      check_inuse_chunk (av, newp);
 	      return newmem;
             }
@@ -5298,7 +5298,7 @@ _int_realloc (mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
                 (av != &main_arena ? NON_MAIN_ARENA : 0));
       /* Mark remainder as inuse so free() won't complain */
       set_inuse_bit_at_offset (remainder, remainder_size);
-      _int_free (av, remainder, 1);
+      _int_free (av, remainder, 1, 0);
     }
 
   check_inuse_chunk (av, newp);
-- 
2.39.5



More information about the Libc-alpha mailing list