Glibc内存管理--ptmalloc2源代码分析(十八)

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 提供了三个函数, 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 节会详细介绍这些内部函数的实现细节。

 

 

 

猜你喜欢

转载自mqzhuang.iteye.com/blog/1064862