Я могу ответить только за jemalloc, но способ, которым он работает, заключается в том, что при создании кеша потока он связывается со специфичными для потока данными для этого потока.
Когда вы создаете данные, специфичные для потока, вы можете присвоить им «деструктор», который вызывается, когда поток уничтожается. Если вы используете pthreads, это подпрограмма pthread_key_create , которая является способом C для создания данных, специфичных для потока.
В случае jemalloc в tcache.h
есть немного кода, который перехватывает tcache_thread_cleanup
с данными tcache
(мой источник jemalloc-3.0.0):
143 malloc_tsd_funcs(JEMALLOC_INLINE, tcache, tcache_t *, NULL,
144 tcache_thread_cleanup)
Итак, когда поток завершается, вызывается деструктор. Он получает указатель на кэш для этого потока и запускает процедуру tcache_thread_cleanup
в это время.