[PATCH] malloc: Remove unused tcache code from unsorted bin scan
Wilco Dijkstra
Wilco.Dijkstra@arm.com
Wed Dec 17 18:17:26 GMT 2025
Now that fastbins have been removed, there is no need to add chunks
to tcache during an unsorted scan. Small blocks can only be added
to unsorted as a result of a remainder chunk split off a larger block,
so there is no point in checking for additional chunks to place in
tcache. The last remainder is checked first, and will be used if it
is large enough or an exact fit. The unsorted bin scan becomes simpler
as a result. Remove the tcache_unsorted_limit tunable.
Passes regress, OK for commit?
---
diff --git a/malloc/arena.c b/malloc/arena.c
index 7ac881309471a00ca906c306d2cd4b92175d14d9..e3e10d39da4510beb1429be244f99727256a77ea 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -238,7 +238,6 @@ TUNABLE_CALLBACK_FNDECL (set_arena_test, size_t)
#if USE_TCACHE
TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t)
TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t)
-TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t)
#endif
TUNABLE_CALLBACK_FNDECL (set_hugetlb, size_t)
@@ -290,8 +289,6 @@ __ptmalloc_init (void)
# if USE_TCACHE
TUNABLE_GET (tcache_max, size_t, TUNABLE_CALLBACK (set_tcache_max));
TUNABLE_GET (tcache_count, size_t, TUNABLE_CALLBACK (set_tcache_count));
- TUNABLE_GET (tcache_unsorted_limit, size_t,
- TUNABLE_CALLBACK (set_tcache_unsorted_limit));
# endif
TUNABLE_GET (hugetlb, size_t, TUNABLE_CALLBACK (set_hugetlb));
diff --git a/malloc/malloc.c b/malloc/malloc.c
index be29929993a2f7f3d269e7d9ed9952cf0d8f109d..e6eac0c27a45395917c131172868f688ff5eb8d8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1797,9 +1797,6 @@ struct malloc_par
size_t tcache_max_bytes;
/* Maximum number of chunks in each bucket. */
size_t tcache_count;
- /* Maximum number of chunks to remove from the unsorted list, which
- aren't used to prefill the cache. */
- size_t tcache_unsorted_limit;
#endif
};
@@ -1832,7 +1829,6 @@ static struct malloc_par mp_ =
.tcache_count = TCACHE_FILL_COUNT,
.tcache_small_bins = TCACHE_SMALL_BINS,
.tcache_max_bytes = MAX_TCACHE_SMALL_SIZE + 1,
- .tcache_unsorted_limit = 0 /* No limit. */
#endif
};
@@ -3824,10 +3820,6 @@ _int_malloc (mstate av, size_t bytes)
mchunkptr fwd; /* misc temp for linking */
mchunkptr bck; /* misc temp for linking */
-#if USE_TCACHE
- size_t tcache_unsorted_count; /* count of unsorted chunks processed */
-#endif
-
/*
Convert request size to internal form by adding SIZE_SZ bytes
overhead plus possibly more to obtain necessary alignment and/or
@@ -3925,24 +3917,8 @@ _int_malloc (mstate av, size_t bytes)
the most recent non-exact fit. Place other traversed chunks in
bins. Note that this step is the only place in any routine where
chunks are placed in bins.
-
- The outer loop here is needed because we might not realize until
- near the end of malloc that we should have consolidated, so must
- do so and retry. This happens at most once, and only when we would
- otherwise need to expand memory to service a "small" request.
*/
-#if USE_TCACHE
- INTERNAL_SIZE_T tcache_nb = 0;
- size_t tc_idx = csize2tidx (nb);
- if (tc_idx < mp_.tcache_small_bins)
- tcache_nb = nb;
- int return_cached = 0;
-
- tcache_unsorted_count = 0;
-#endif
-
- for (;; )
{
int iters = 0;
while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
@@ -4012,28 +3988,10 @@ _int_malloc (mstate av, size_t bytes)
set_inuse_bit_at_offset (victim, size);
if (av != &main_arena)
set_non_main_arena (victim);
-#if USE_TCACHE
- if (__glibc_unlikely (tcache_inactive ()))
- tcache_init (av);
- /* Fill cache first, return to user only if cache fills.
- We may return one of these chunks later. */
- if (tcache_nb > 0
- && tcache->num_slots[tc_idx] != 0)
- {
- tcache_put (victim, tc_idx);
- return_cached = 1;
- continue;
- }
- else
- {
-#endif
check_malloced_chunk (av, victim, nb);
void *p = chunk2mem (victim);
alloc_perturb (p, bytes);
return p;
-#if USE_TCACHE
- }
-#endif
}
/* Place chunk in bin. Only splitting can put
@@ -4107,31 +4065,11 @@ _int_malloc (mstate av, size_t bytes)
fwd->bk = victim;
bck->fd = victim;
-#if USE_TCACHE
- /* If we've processed as many chunks as we're allowed while
- filling the cache, return one of the cached ones. */
- ++tcache_unsorted_count;
- if (return_cached
- && mp_.tcache_unsorted_limit > 0
- && tcache_unsorted_count > mp_.tcache_unsorted_limit)
- {
- return tcache_get (tc_idx);
- }
-#endif
-
#define MAX_ITERS 10000
if (++iters >= MAX_ITERS)
break;
}
-#if USE_TCACHE
- /* If all the small chunks we found ended up cached, return one now. */
- if (return_cached)
- {
- return tcache_get (tc_idx);
- }
-#endif
-
/*
If a large request, scan through the chunks of current bin in
sorted order to find smallest that fits. Use the skip list for this.
@@ -5111,13 +5049,6 @@ do_set_tcache_count (size_t value)
return 0;
}
-static __always_inline int
-do_set_tcache_unsorted_limit (size_t value)
-{
- LIBC_PROBE (memory_tunable_tcache_unsorted_limit, 2, value, mp_.tcache_unsorted_limit);
- mp_.tcache_unsorted_limit = value;
- return 1;
-}
#endif
static __always_inline int
More information about the Libc-alpha
mailing list