[PATCH] malloc: move tcache_init out of hot tcache paths
Cupertino Miranda
cupertino.miranda@oracle.com
Fri Apr 11 09:07:58 GMT 2025
Hi everyone,
Looking forward to your review.
I will reply to this patch with some benchmarking charts on a small
machine x86 machinei (AMD GX-222GC SOC).
In any case the content of the patch can only improve performance.
Cheers,
Cupertino
---
This patch moves any calls of tcache_init away after tcache hot paths.
Since there is no reazon to initialize tcaches in the hot path and
since we need to be able to check tcache != NULL in any case, because of
tcache_thread_shutdown function, moving tcache_init away from hot path
can only be beneficial.
It adds 2 extra checks for tcache != NULL in non regular allocation
paths to resolve regressions.
---
malloc/malloc.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index a0bc733482..ed7f271693 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3345,6 +3345,7 @@ tcache_init(void)
if (__glibc_unlikely (tcache == NULL)) \
tcache_init();
+
/* Trying to alloc BYTES from tcache. If tcache is available, chunk
is allocated and stored to MEMPTR, otherwise, MEMPTR is NULL.
It returns true if error occurs, else false. */
@@ -3361,13 +3362,16 @@ tcache_try_malloc (size_t bytes, void **memptr)
size_t tc_idx = csize2tidx (tbytes);
- MAYBE_INIT_TCACHE ();
if (tcache_available (tc_idx))
- *memptr = tcache_get (tc_idx);
+ {
+ *memptr = tcache_get (tc_idx);
+ return false;
+ }
else
*memptr = NULL;
+ MAYBE_INIT_TCACHE ();
return false;
}
@@ -3393,8 +3397,6 @@ __libc_malloc2 (size_t bytes)
if (!__malloc_initialized)
ptmalloc_init ();
- MAYBE_INIT_TCACHE ();
-
if (SINGLE_THREAD_P)
{
victim = tag_new_usable (_int_malloc (&main_arena, bytes));
@@ -3433,6 +3435,8 @@ __libc_malloc (size_t bytes)
if (tcache_available (tc_idx))
return tag_new_usable (tcache_get (tc_idx));
+ else
+ MAYBE_INIT_TCACHE ();
#endif
return __libc_malloc2 (bytes);
@@ -3474,8 +3478,6 @@ __libc_free (void *mem)
}
else
{
- MAYBE_INIT_TCACHE ();
-
/* Mark the chunk as belonging to the library again. */
(void)tag_region (chunk2mem (p), memsize (p));
@@ -3696,8 +3698,6 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
}
size_t tc_idx = csize2tidx (tbytes);
- MAYBE_INIT_TCACHE ();
-
if (tcache_available (tc_idx))
{
/* The tcache itself isn't encoded, but the chain is. */
@@ -3715,6 +3715,7 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
}
}
}
+ MAYBE_INIT_TCACHE ();
#endif
if (SINGLE_THREAD_P)
@@ -4299,6 +4300,7 @@ _int_malloc (mstate av, size_t bytes)
filling the cache, return one of the cached ones. */
++tcache_unsorted_count;
if (return_cached
+ && __glibc_likely (tcache != NULL)
&& mp_.tcache_unsorted_limit > 0
&& tcache_unsorted_count > mp_.tcache_unsorted_limit)
{
@@ -4313,7 +4315,8 @@ _int_malloc (mstate av, size_t bytes)
#if USE_TCACHE
/* If all the small chunks we found ended up cached, return one now. */
- if (return_cached)
+ if (return_cached
+ && __glibc_likely (tcache != NULL))
{
return tcache_get (tc_idx);
}
--
2.30.2
More information about the Libc-alpha
mailing list