Sword nginx slab源码解析三(页分配)
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; }