Glibcメモリ管理--ptmalloc 2ソースコード分析(18)


5.5 Ptmalloc初期化
 
Ptmallocの初期化はプロセスの最初のメモリ割り当て要求で発生し、ptmallocの初期化は一般的にユーザの最初のmalloc()またはremalloc()を呼び出す前に、オペレーティングシステムとGlibcライブラリがプロセスの初期化のために多くの仕事をしたため、ユーザ割り当てが保存される前にGlibcは複数回のメモリを割り当てた.
ptmallocにおけるmalloc()関数の実際のインタフェース関数はpublic_mALLOc()は、この関数が最初に次のコードを実行します.
__malloc_ptr_t (*hook) (size_t, __const __malloc_ptr_t)
    = force_reg (__malloc_hook);
  if (__builtin_expect (hook != NULL, 0))
    return (*hook)(bytes, RETURN_ADDRESS (0));

定義されている_malloc_hook()グローバル関数の場合は、実行__のみmalloc_hook()関数、プロセス初期化時_malloc_hookが指す関数はmalloc_hook_ini() .
__malloc_ptr_t weak_variable (*__malloc_hook)
     (size_t __size, const __malloc_ptr_t) = malloc_hook_ini;

 malloc_hook_ini()関数はhooksで定義する.cでは、実装コードは以下の通りである.
static Void_t*
#if __STD_C
malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
#else
malloc_hook_ini(sz, caller)
     size_t sz; const __malloc_ptr_t caller;
#endif
{
  __malloc_hook = NULL;
  ptmalloc_init();
  return public_mALLOc(sz);
}

 malloc_hook_ini()関数の処理は簡単です.ptmallocの初期化関数ptmalloc_を呼び出すことです.init()を呼び出し、pbulit_を再呼び出します.mALLOc()関数はメモリを割り当てます.Ptmalloc_Init()関数ptmallocの初期化が完了すると、グローバル変数_malloc_initializedが1に設定されている場合、pbulit_mALLOc()関数を再実行する場合は、まずmalloc_を実行します.hook_ini()関数、malloc_hook_ini()関数呼び出しptmalloc_init() , ptmalloc_init()関数まず判断_malloc_initializedが1であるかどうか、もしそうであればptmalloc_を終了します.Init()は、ptmalloc初期化を実行しません.
 
5.5.1 Ptmallocが初期化されていない場合のメモリの割り当て/解放
ptmallocの初期化関数ptmalloc_Init()が呼び出される前に、Glibcではスレッドプライベートインスタンスの初期化などのメモリの割り当てが必要になる可能性があります.この問題を解決するために、ptmallocは内部の割り当て解放関数をカプセル化して、この場合に使用します.Ptmallocは3つの関数を提供しています.malloc_starter() , memalign_starter() , free_starter()ですがrealloc_は提供されていませんstarter()関数.これらの関数の実装は次のとおりです.
static Void_t*
#if __STD_C
malloc_starter(size_t sz, const Void_t *caller)
#else
malloc_starter(sz, caller) size_t sz; const Void_t *caller;
#endif
{
  Void_t* victim;

  victim = _int_malloc(&main_arena, sz);

  return victim ? BOUNDED_N(victim, sz) : 0;
}

static Void_t*
#if __STD_C
memalign_starter(size_t align, size_t sz, const Void_t *caller)
#else
memalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller;
#endif
{
  Void_t* victim;

  victim = _int_memalign(&main_arena, align, sz);

  return victim ? BOUNDED_N(victim, sz) : 0;
}

static void
#if __STD_C
free_starter(Void_t* mem, const Void_t *caller)
#else
free_starter(mem, caller) Void_t* mem; const Void_t *caller;
#endif
{
  mchunkptr p;

  if(!mem) return;
  p = mem2chunk(mem);
#if HAVE_MMAP
  if (chunk_is_mmapped(p)) {
    munmap_chunk(p);
    return;
  }
#endif
#ifdef ATOMIC_FASTBINS
  _int_free(&main_arena, p, 1);
#else
  _int_free(&main_arena, p);
#endif
}

この関数の実装はすべて簡単で、ptmallocの内部実装関数を呼び出すだけで、ここでは内部関数の実装について詳しく説明しません.5.7と5.8節では、これらの内部関数の実装の詳細について詳しく説明します.