• 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;
    }

  • 相关阅读:
    linux 进程学习笔记-运行新进程
    linux 进程学习笔记-进程状态
    linux 进程学习笔记-进程调度
    linux 进程学习笔记-进程退出/终止进程
    linux 进程学习笔记-暂停进程
    linux 进程学习笔记-进程跟踪
    linux 进程学习笔记-等待子进程结束
    linux 进程学习笔记-进程pipe管道
    linux 进程学习笔记-named pipe (FIFO)命名管道
    linux 进程学习笔记-进程信号sigal
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/16511753.html
Copyright © 2020-2023  润新知