malloc読んでみた4 chunkとrun
chunkはarenaのrunが作られるときにmmapで取り出される
メモリーの領域です。
arena_run_allocを見てみましょう。
arenaのrun_avail内にすでにメモリーが取られている場合は
そのメモリーをrunとして返します。
mapelm = arena_avail_tree_nsearch(&arena->runs_avail, &key);
if (mapelm != NULL) {
arena_chunk_t *run_chunk = CHUNK_ADDR2BASE(mapelm);
size_t pageind = ( (uintptr_t)mapelm - (uintptr_t)run_chunk->map)
/ sizeof(arena_chunk_map_t);
run = (arena_run_t *)( (uintptr_t)run_chunk + (pageind
<< PAGE_SHIFT));
arena_run_split(arena, run, size, large, zero);
return (run);
}
その際にarena_run_splitでそのrunをarena->runs_availのtreeから切り離しています。
chunkは複数のpageに分けられて管理されており。
そのpageの中の現在使われている。メモリーをchunk->map[run_ind]でアクセスできるようになっています。
同じことは
run = (arena_run_t *)( (uintptr_t)run_chunk + (pageind
<< PAGE_SHIFT));
という形でアクセスされることもあります。
このpageindは
size_t pageind = ((uintptr_t)mapelm - (uintptr_t)run_chunk->map)
/ sizeof(arena_chunk_map_t);
のようにrun_chunkの位置によって決められています。
arenaのrun_avail内にメモリーがない場合はarena_chunk_allocでメモリーを取得します。arena_chunk_allocではchunkが作られarena->runs_availに一度挿入されます。
chunk = (arena_chunk_t *)chunk_alloc(chunksize, &zero);
...
arena_avail_tree_insert(&arena->runs_avail,
&chunk->map[arena_chunk_header_npages]);
return (chunk);
そのあとarena_run_splitでtreeから切り離されます。
chunkとはmallocが管理するメモリーの大きな単位でそのchunkの中で現在使われているものがrunだということになります。