static ngx_slab_page_t* ngx_slab_alloc_pages(ngx_slab_pool_t* pool, ngx_uint_t pages)
{
ngx_slab_page_t *page, *p;
for (page = pool->free.next; page != &pool->free; page = page->next)
{
if (page->slab >= pages)
{
// 当前剩余页数 大于 需求页数
if (page->slab > pages)
{
/*
设计说明:
page->slab 记录可用的页数
pages 需要申请的页数
那么被申请的页数即page[0] page[1] page[pages - 1]
剩下的空闲页是 page[pages]
备注:
不要把page看成数组,应该把page看成指针,page[pages] 即 page + pages
page 不等于 pool->pages
*/
page[page->slab - 1].prev = (uintptr_t) &page[pages];
// 更新新free页信息
page[pages].slab = page->slab - pages;
page[pages].next = page->next;
page[pages].prev = page->prev;
// 将已使用页从空闲链表上摘除
p = (ngx_slab_page_t *) page->prev;
// 空闲链表头指向下一个空闲页
p->next = &page[pages];
page->next->prev = (uintptr_t) &page[pages];
}
else
{
// 所有的空闲页恰好被用完
p = (ngx_slab_page_t *) page->prev;
p->next = page->next;
page->next->prev = page->prev;
}
// 更新使用页节点信息
// 记录当前页管理了多少页
page->slab = pages | NGX_SLAB_PAGE_START;
page->next = NULL;
// 标记页的类型
page->prev = NGX_SLAB_PAGE;
// 更新空闲页数
pool->pfree -= pages;
if (--pages == 0)
{
return page;
}
for (p = page + 1; pages; pages--)
{
// 更新分配每一页的页信息
p->slab = NGX_SLAB_PAGE_BUSY;
p->next = NULL;
p->prev = NGX_SLAB_PAGE;
p++;
}
return page;
}
}
if (pool->log_nomem) {
ngx_slab_error(pool, NGX_LOG_CRIT,
"ngx_slab_alloc() failed: no memory");
}
return NULL;
}
![]()
![]()
![]()
![]()