• Sword nginx slab源码解析二(初始化)


    /*
    设计说明:
        当page划分的slot块小于128个字节时候,pre的后两位为NGX_SLAB_SMALL
        当page划分的slot块等于128个字节时候,pre的后两位为NGX_SLAB_EXACT
        当page划分的slot块大于128个字节时候,pre的后两位为NGX_SLAB_BIG
        当page划分的slot块大于2048个字节时候,pre的后两位为NGX_SLAB_PAGE
    */
    #define NGX_SLAB_PAGE_MASK   3
    #define NGX_SLAB_PAGE        0
    #define NGX_SLAB_BIG         1
    #define NGX_SLAB_EXACT       2
    #define NGX_SLAB_SMALL       3
    
    #if (NGX_PTR_SIZE == 4)
    
    #define NGX_SLAB_PAGE_FREE   0
    #define NGX_SLAB_PAGE_BUSY   0xffffffff
    #define NGX_SLAB_PAGE_START  0x80000000
    
    #define NGX_SLAB_SHIFT_MASK  0x0000000f
    #define NGX_SLAB_MAP_MASK    0xffff0000
    #define NGX_SLAB_MAP_SHIFT   16
    
    #define NGX_SLAB_BUSY        0xffffffff
    
    #else /* (NGX_PTR_SIZE == 8) */
    
    #define NGX_SLAB_PAGE_FREE   0
    #define NGX_SLAB_PAGE_BUSY   0xffffffffffffffff
    #define NGX_SLAB_PAGE_START  0x8000000000000000
    
    #define NGX_SLAB_SHIFT_MASK  0x000000000000000f
    #define NGX_SLAB_MAP_MASK    0xffffffff00000000
    #define NGX_SLAB_MAP_SHIFT   32
    
    #define NGX_SLAB_BUSY        0xffffffffffffffff
    
    #endif
    
    
    #define ngx_slab_slots(pool)                                                  \
        (ngx_slab_page_t *) ((u_char *) (pool) + sizeof(ngx_slab_pool_t))
    
    #define ngx_slab_page_type(page)   ((page)->prev & NGX_SLAB_PAGE_MASK)
    
    #define ngx_slab_page_prev(page)                                              \
        (ngx_slab_page_t *) ((page)->prev & ~NGX_SLAB_PAGE_MASK)
    
    #define ngx_slab_page_addr(pool, page)                                        \
        ((((page) - (pool)->pages) << ngx_pagesize_shift)                         \
         + (uintptr_t) (pool)->start)
    
    
    #if (NGX_DEBUG_MALLOC)
    
    #define ngx_slab_junk(p, size)     ngx_memset(p, 0xA5, size)
    
    #elif (NGX_HAVE_DEBUG_MALLOC)
    
    #define ngx_slab_junk(p, size)                                                \
        if (ngx_debug_malloc)          ngx_memset(p, 0xA5, size)
    
    #else
    
    #define ngx_slab_junk(p, size)
    
    #endif
    
    static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
        ngx_uint_t pages);
    static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
        ngx_uint_t pages);
    static void ngx_slab_error(ngx_slab_pool_t *pool, ngx_uint_t level,
        char *text);
    
    
    static ngx_uint_t  ngx_slab_max_size;
    static ngx_uint_t  ngx_slab_exact_size;
    static ngx_uint_t  ngx_slab_exact_shift;
    
    
    void ngx_slab_sizes_init(void)
    {
        ngx_uint_t  n;
    
        /*
        知识补充:
            32位机器上,ngx_pagesize一般为4096字节
        */
    
        /*
        设计说明:
            ngx_slab_max_size 2048字节
            ngx_slab_exact_size 128字节
            ngx_slab_exact_shift 7    ngx_slab_exact_size对应的页偏移量,4096对应的偏移量是12
        */
    
        ngx_slab_max_size = ngx_pagesize / 2;
        ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));
        for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) 
        {
            /* void */
        }
    }
    
    
    void ngx_slab_init(ngx_slab_pool_t *pool)
    {
        u_char           *p;
        size_t            size;
        ngx_int_t         m;
        ngx_uint_t        i, n, pages;
        ngx_slab_page_t  *slots, *page;
    
        // 设置可以分配的最小字节数,pool->min_shift默认是3,即pool->min_size = 8
        pool->min_size = (size_t) 1 << pool->min_shift;
    
        // 获取slot相对地址
        slots = ngx_slab_slots(pool);
    
        p = (u_char *) slots;
    
        // 获取slab池子大小
        size = pool->end - p;
    
        // 初始化数据(没啥意义)
        ngx_slab_junk(p, size);
        /*
        设计说明:
            ngx_pagesize_shift 是页偏移量,4096字节的偏移量是12
        */
        n = ngx_pagesize_shift - pool->min_shift;
    
        /*
        设计说明:
            slot 一般只用来标记 8 16 32 64 128 256 512 1024 2048 一个9个
        */
        for (i = 0; i < n; i++) 
        {
            /* only "next" is used in list head */
            slots[i].slab = 0;
            slots[i].next = &slots[i];
            slots[i].prev = 0;
        }
    
        // 跳过slot列表
        p += n * sizeof(ngx_slab_page_t);
    
        // 设置slab池状态
        pool->stats = (ngx_slab_stat_t *) p;
        ngx_memzero(pool->stats, n * sizeof(ngx_slab_stat_t));
    
        // 跳过stats列表
        p += n * sizeof(ngx_slab_stat_t);
    
        // 更新size,刨除 slots+stats
        size -= n * (sizeof(ngx_slab_page_t) + sizeof(ngx_slab_stat_t));
    
        // 计算剩余页数
        pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
    
        pool->pages = (ngx_slab_page_t *) p;
        ngx_memzero(pool->pages, pages * sizeof(ngx_slab_page_t));
    
        // 页数据
        page = pool->pages;
    
        /* only "next" is used in list head */
        pool->free.slab = 0;
        pool->free.next = page;
        pool->free.prev = 0;
    
        // 记录可以分配的页数目
        page->slab = pages;
        page->next = &pool->free;
        page->prev = (uintptr_t) &pool->free;
    
        // 设置起始点(字节对齐)
        pool->start = ngx_align_ptr(p + pages * sizeof(ngx_slab_page_t),
                                    ngx_pagesize);
    
        /*
        设计说明:
            因为字节对齐,会浪费一定的内存空间,因此需要重新计算pages
        */
        m = pages - (pool->end - pool->start) / ngx_pagesize;
        if (m > 0) {
            pages -= m;
            page->slab = pages;
        }
    
        // 设置slab池的末尾节点
        pool->last = pool->pages + pages;
        pool->pfree = pages;
    
        pool->log_nomem = 1;
        pool->log_ctx = &pool->zero;
        pool->zero = '\0';
    }
  • 相关阅读:
    “同形异义字”钓鱼攻击
    研发管理101军规#001 两周迭代,形成团队持续习惯
    全新 PingCode 正式发布
    Python基础数据类型——tuple浅析
    Python基础变量类型——List浅析
    有了这个神器,快速告别垃圾短信邮件
    零基础打造一款属于自己的网页搜索引擎
    一篇文章教会你使用Python网络爬虫下载酷狗音乐
    趣味解读Python面向对象编程 (类和对象)
    上古神器Gvim--从入门到精通
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/16511743.html
Copyright © 2020-2023  润新知