[patch v2] malloc: avoid need for tcache == NULL checks
Florian Weimer
fw@deneb.enyo.de
Thu Aug 28 21:14:35 GMT 2025
* DJ Delorie:
> Avoid needing to check for tcache == NULL by initializing it
> to a dummy read-only tcache structure. This dummy is all zeros,
> so logically it is both full (when you want to put) and empty (when
> you want to get). Also, there are two dummies, one used for
> "not yet initialized" and one for "tunables say we shouldn't have
> a tcache".
>
> The net result is twofold:
>
> 1. Checks for tcache == NULL may be removed from the fast path.
> Whether this makes the fast path faster when tcache is
> disabled is TBD, but the normal case is tcache enabled.
>
> 2. no memory for tcache is allocated if tunables disable caching.
> +/* TCACHE is never NULL; it's either "live" or points to one of the
> + above dummy entries. The dummy entries are all zero so act like an
> + empty/unusable tcache. */
> +static __thread tcache_perthread_struct *tcache = (tcache_perthread_struct *) &__tcache_dummy.inactive;
> +
> +/* This is the default, and means "check to see if a real tcache
> + should be allocated." */
> +#define TCACHE_INACTIVE() (tcache == &__tcache_dummy.inactive)
> +/* This means "the user has disabled the tcache but we have to point
> + to something." */
> +#define TCACHE_DISABLED() (tcache == &__tcache_dummy.disabled)
> +/* This means the tcache is active. */
> +#define TCACHE_ENABLED() (!TCACHE_INACTIVE() && !TCACHE_DISABLED())
> +/* Sets the tcache to INACTIVE state. */
> +#define TCACHE_SET_INACTIVE() tcache = (tcache_perthread_struct *) &__tcache_dummy.inactive;
> +/* Sets the tcache to DISABLED state. */
> +#define TCACHE_SET_DISABLED() tcache = (tcache_perthread_struct *) &__tcache_dummy.disabled;
I suppose these could be inline functions instead of macros. I've got
the impression
> @@ -3305,14 +3332,14 @@ tcache_thread_shutdown (void)
> {
> int i;
> tcache_perthread_struct *tcache_tmp = tcache;
> + int need_free = TCACHE_ENABLED ();
>
> tcache_shutting_down = true;
Isn't tcache_shutting_down now redundant? Because we have
TCACHE_SET_DISABLED?
> @@ -3388,6 +3411,11 @@ __libc_malloc2 (size_t bytes)
> mstate ar_ptr;
> void *victim;
>
> +#if USE_TCACHE
> + if (__glibc_unlikely (TCACHE_INACTIVE ()))
> + tcache_init ();
> +#endif
Could this be moved to the
> if (SINGLE_THREAD_P)
> {
> victim = tag_new_usable (_int_malloc (&main_arena, bytes));
> @@ -3427,8 +3455,6 @@ __libc_malloc (size_t bytes)
> if (nb < mp_.tcache_max_bytes)
> {
> size_t tc_idx = csize2tidx (nb);
> - if(__glibc_unlikely (tcache == NULL))
> - return tcache_malloc_init (bytes);
tcache path here?
More information about the Libc-alpha
mailing list