[PATCH] malloc: Remove unused tcache code from unsorted bin scan
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Fri Feb 6 13:14:45 GMT 2026
On 27/01/26 15:10, Wilco Dijkstra wrote:
> ping
>
>
> 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.
Now that tcache_unsorted_limit is not used anywhere, I think it should be
removed from manual (manual/probes.texi and manual/tunables.texi), along
with the tunables definition (elf/dl-tunables.list) and related tests
(elf/tst-rtld-list-tunables.exp).
The rest looks ok.
>
> 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