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だということになります。