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 节会详细介绍这些内部函数的实现细节。
349

被折叠的 条评论
为什么被折叠?



