此函数经由某些宏开关,被分成了两个部分.
而实际,主要是从170行开始.之前的是另一个部分.
这个函数主要做的是,从free链表里面获取lengt大小的内存块.
如果没有合适大小的块,则用my_malloc申请新的块.
得到块之后,并没有讲块从free里移除.依然在free链表里.
内存块的大小也是不固定的.
alloc_root的代码
// mysys/my_alloc.c
void *alloc_root(MEM_ROOT *mem_root, size_t length)
{
#if defined(HAVE_purify) && defined(EXTRA_DEBUG)
reg1 USED_MEM *next;
DBUG_ENTER("alloc_root");
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
DBUG_ASSERT(alloc_root_inited(mem_root));
length+=ALIGN_SIZE(sizeof(USED_MEM));
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME))))
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
DBUG_RETURN((uchar*) 0); /* purecov: inspected */
}
next->next= mem_root->used;
next->size= length;
mem_root->used= next; // 将next链接到root链表
DBUG_PRINT("exit",("ptr: 0x%lx", (long) (((char*) next)+
ALIGN_SIZE(sizeof(USED_MEM)))));
DBUG_RETURN((uchar*) (((char*) next)+ALIGN_SIZE(sizeof(USED_MEM))));
#else
size_t get_size, block_size;
uchar* point;
reg1 USED_MEM *next= 0;
reg2 USED_MEM **prev;
DBUG_ENTER("alloc_root");
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
DBUG_ASSERT(alloc_root_inited(mem_root));
length= ALIGN_SIZE(length);
if ((*(prev= &mem_root->free)) != NULL) //有可用内存区域,此时prev与free链表指向相同.
{
if ((*prev)->left < length &&
mem_root->first_block_usage++ >= ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP &&
(*prev)->left < ALLOC_MAX_BLOCK_TO_DROP)
{
next= *prev;
*prev= next->next; /* Remove block from list */
next->next= mem_root->used;
mem_root->used= next;
mem_root->first_block_usage= 0;
}
for (next= *prev ; next && next->left < length ; next= next->next)
prev= &next->next;
}
if (! next) //上面的例程没找到合适大小的内存块,则申请新的内存区域
{ /* Time to alloc new block */
block_size= mem_root->block_size * (mem_root->block_num >> 2);
get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
get_size= max(get_size, block_size);
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
{
if (mem_root->error_handler)
(*mem_root->error_handler)();
return((void*) 0); /* purecov: inspected */
}
mem_root->block_num++;
next->next= *prev; //将新块添加到free链表头部
next->size= get_size;
next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM));
*prev=next; //重新让pre指向free链表头部
}
//获得内存块之后,减去链表数据结构的大小,得到实际可用内存块大小的起点.
point= (uchar*) ((char*) next+ (next->size-next->left));
/*TODO: next part may be unneded due to mem_root->first_block_usage counter*/
if ((next->left-= length) < mem_root->min_malloc)
{ /* Full block */
*prev= next->next; /* Remove block from list */
next->next= mem_root->used;
mem_root->used= next;
mem_root->first_block_usage= 0;
}
DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point));
DBUG_RETURN((void*) point);// 返回实际可用内存块的起始位置指针.此时内存块已经列入free链表里
#endif
}
没有评论:
发表评论