⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_slab.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>/*                         12    2048   2             11    1024   4             10    512    8             9    256   16             8    128   32   4   32    7    64    64   8   63    6      1    32   128  16  127    5      1    16   256  32  254    4      2    8    512  64  504    3      8 */#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#if (NGX_DEBUG_MALLOC)#define ngx_slab_junk(p, size)     ngx_memset(p, 0xD0, size)#else#if (NGX_FREEBSD)#define ngx_slab_junk(p, size)                                                \    if (ngx_freebsd_debug_malloc)  ngx_memset(p, 0xD0, size)#else#define ngx_slab_junk(p, size)#endif#endifstatic 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 ngx_uint_t  ngx_slab_max_size;static ngx_uint_t  ngx_slab_exact_size;static ngx_uint_t  ngx_slab_exact_shift;voidngx_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;    /* STUB */    if (ngx_slab_max_size == 0) {        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 */        }    }    /**/    pool->min_size = 1 << pool->min_shift;    p = (u_char *) pool + sizeof(ngx_slab_pool_t);    size = pool->end - p;    ngx_slab_junk(p, size);    slots = (ngx_slab_page_t *) p;    n = ngx_pagesize_shift - pool->min_shift;    for (i = 0; i < n; i++) {        slots[i].slab = 0;        slots[i].next = &slots[i];        slots[i].prev = 0;    }    p += n * sizeof(ngx_slab_page_t);    pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));    ngx_memzero(p, pages * sizeof(ngx_slab_page_t));    pool->pages = (ngx_slab_page_t *) p;    pool->free.prev = 0;    pool->free.next = (ngx_slab_page_t *) p;    pool->pages->slab = pages;    pool->pages->next = &pool->free;    pool->pages->prev = (uintptr_t) &pool->free;    pool->start = (u_char *)                  ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),                                 ngx_pagesize);    m = pages - (pool->end - pool->start) / ngx_pagesize;    if (m > 0) {        pages -= m;        pool->pages->slab = pages;    }#if 0    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "slab: %p, %p, %ui, %d",                  pool, pool->start, pages,                  (pool->end - pool->start) / ngx_pagesize - pages);#endif}void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size){    void  *p;    ngx_shmtx_lock(&pool->mutex);    p = ngx_slab_alloc_locked(pool, size);    ngx_shmtx_unlock(&pool->mutex);    return p;}void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size){    size_t            s;    uintptr_t         p, n, m, mask, *bitmap;    ngx_uint_t        i, slot, shift, map;    ngx_slab_page_t  *page, *prev, *slots;    if (size >= ngx_slab_max_size) {        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,                       "slab alloc: %uz", size);        page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1)                                          >> ngx_pagesize_shift);        if (page) {            p = (page - pool->pages) << ngx_pagesize_shift;            p += (uintptr_t) pool->start;        } else {            p = 0;        }        goto done;    }    if (size > pool->min_size) {        shift = 1;        for (s = size - 1; s >>= 1; shift++) { /* void */ }        slot = shift - pool->min_shift;    } else {        size = pool->min_size;        shift = pool->min_shift;        slot = 0;    }    ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,                   "slab alloc: %uz slot: %ui", size, slot);    slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));    page = slots[slot].next;    if (page->next != page) {        if (shift < ngx_slab_exact_shift) {            do {                p = (page - pool->pages) << ngx_pagesize_shift;                bitmap = (uintptr_t *) (pool->start + p);                map = (1 << (ngx_pagesize_shift - shift))                          / (sizeof(uintptr_t) * 8);                for (n = 0; n < map; n++) {                    if (bitmap[n] != NGX_SLAB_BUSY) {                        for (m = 1, i = 0; m; m <<= 1, i++) {                            if ((bitmap[n] & m)) {                                continue;                            }                            bitmap[n] |= m;                            i = ((n * sizeof(uintptr_t) * 8) << shift)                                + (i << shift);                            if (bitmap[n] == NGX_SLAB_BUSY) {                                for (n = n + 1; n < map; n++) {                                     if (bitmap[n] != NGX_SLAB_BUSY) {                                         p = (uintptr_t) bitmap + i;                                         goto done;                                     }                                }                                prev = (ngx_slab_page_t *)                                            (page->prev & ~NGX_SLAB_PAGE_MASK);                                prev->next = page->next;                                page->next->prev = page->prev;                                page->next = NULL;                                page->prev = NGX_SLAB_SMALL;                            }                            p = (uintptr_t) bitmap + i;                            goto done;                        }                    }                }                page = page->next;            } while (page);        } else if (shift == ngx_slab_exact_shift) {            do {                if (page->slab != NGX_SLAB_BUSY) {                    for (m = 1, i = 0; m; m <<= 1, i++) {                        if ((page->slab & m)) {                            continue;                        }                        page->slab |= m;                        if (page->slab == NGX_SLAB_BUSY) {                            prev = (ngx_slab_page_t *)                                            (page->prev & ~NGX_SLAB_PAGE_MASK);                            prev->next = page->next;                            page->next->prev = page->prev;                            page->next = NULL;                            page->prev = NGX_SLAB_EXACT;                        }                        p = (page - pool->pages) << ngx_pagesize_shift;                        p += i << shift;                        p += (uintptr_t) pool->start;                        goto done;                    }                }                page = page->next;            } while (page);        } else { /* shift > ngx_slab_exact_shift */            n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);            n = 1 << n;            n = ((uintptr_t) 1 << n) - 1;            mask = n << NGX_SLAB_MAP_SHIFT;            do {                if ((page->slab & NGX_SLAB_MAP_MASK) != mask) {                    for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;                         m & mask;                         m <<= 1, i++)                    {                        if ((page->slab & m)) {                            continue;                        }                        page->slab |= m;                        if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {                            prev = (ngx_slab_page_t *)                                            (page->prev & ~NGX_SLAB_PAGE_MASK);                            prev->next = page->next;                            page->next->prev = page->prev;                            page->next = NULL;                            page->prev = NGX_SLAB_BIG;                        }                        p = (page - pool->pages) << ngx_pagesize_shift;                        p += i << shift;                        p += (uintptr_t) pool->start;                        goto done;                    }                }                page = page->next;            } while (page);        }    }    page = ngx_slab_alloc_pages(pool, 1);    if (page) {        if (shift < ngx_slab_exact_shift) {            p = (page - pool->pages) << ngx_pagesize_shift;            bitmap = (uintptr_t *) (pool->start + p);            s = 1 << shift;            n = (1 << (ngx_pagesize_shift - shift)) / 8 / s;            if (n == 0) {                n = 1;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -