tcache(Thread local Caching)란 멀티 스레드 환경에서 메모리 할당 속도를 높이기 위한 것으로 각 스레드에 독립적으로 할당되는 캐시 저장소이다.
작은 단위의 메모리는 arena를 참조하지 않고 바로 메모리를 할당한다.
glibc2.26 버전 이상부터 도입되었으며, 멀티 스레드 환경에 더욱 최적화된 메모리 관리 메커니즘을 제공한다.
※arena?
-> 멀티스레드 환경을 지원하기 위해 도입되었다.
-> fastbin, smallbin, largebin 등의 정보를 모두 담고있는 객체이다.
-> 과도한 멀티 쓰레드 환경에서는 병목 현상이 발생한다.
/* We overlay this structure on the user-data portion of a chunk when
the chunk is stored in the per-thread cache. */
typedef struct tcache_entry
{
struct tcache_entry *next;
} tcache_entry;
/* There is one of these for each thread, which contains the
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */
typedef struct tcache_perthread_struct
{
char counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
# define TCACHE_MAX_BINS 64
static __thread tcache_perthread_struct *tcache = NULL;
struct malloc_chunk {
size_t mchunk_prev_size; /* Size of previous chunk (if free). */
size_t mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
IDX = (CHUNKSIZE - MINSIZE + MALLOC_ALIGNMENT -1) / MALLOC_ALIGNMENT
이때 64bit 에서는 MINSIZE = 0x20, MALLOC_ALIGNMENT = 0x10이다.
따라서, IDX = (CHUNKSIZE - 0x11) / 0x10 이 된다.
CHUNKSIZE와 malloc(x)의 x는 같은 값이 아님을 조심하자
여기서 & ~0xf는 (x + 0x8 + 0xf)의 하위 4비트를 날리는 행위이다.
tcache idx의 계산 방법을 알려주는 코드이다.