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

📄 ngx_slab.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
            bitmap[0] = (2 << n) - 1;            map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);            for (i = 1; i < map; i++) {                bitmap[i] = 0;            }            page->slab = shift;            page->next = &slots[slot];            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;            slots[slot].next = page;            p = ((page - pool->pages) << ngx_pagesize_shift) + s * n;            p += (uintptr_t) pool->start;            goto done;        } else if (shift == ngx_slab_exact_shift) {            page->slab = 1;            page->next = &slots[slot];            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;            slots[slot].next = page;            p = (page - pool->pages) << ngx_pagesize_shift;            p += (uintptr_t) pool->start;            goto done;        } else { /* shift > ngx_slab_exact_shift */            page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;            page->next = &slots[slot];            page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;            slots[slot].next = page;            p = (page - pool->pages) << ngx_pagesize_shift;            p += (uintptr_t) pool->start;            goto done;        }    }    p = 0;done:    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);    return (void *) p;}voidngx_slab_free(ngx_slab_pool_t *pool, void *p){    ngx_shmtx_lock(&pool->mutex);    ngx_slab_free_locked(pool, p);    ngx_shmtx_unlock(&pool->mutex);}voidngx_slab_free_locked(ngx_slab_pool_t *pool, void *p){    size_t            size;    uintptr_t         slab, m, *bitmap;    ngx_uint_t        n, type, slot, shift, map;    ngx_slab_page_t  *slots, *page;    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);    if ((u_char *) p < pool->start || (u_char *) p > pool->end) {        ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,                      "ngx_slab_free(): outside of pool");        goto fail;    }    n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;    page = &pool->pages[n];    slab = page->slab;    type = page->prev & NGX_SLAB_PAGE_MASK;    switch (type) {    case NGX_SLAB_SMALL:        shift = slab & NGX_SLAB_SHIFT_MASK;        size = 1 << shift;        if ((uintptr_t) p & (size - 1)) {            goto wrong_chunk;        }        n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;        m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));        n /= (sizeof(uintptr_t) * 8);        bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));        if (bitmap[n] & m) {            if (page->next == NULL) {                slots = (ngx_slab_page_t *)                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));                slot = shift - pool->min_shift;                page->next = slots[slot].next;                slots[slot].next = page;                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;                page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;            }            bitmap[n] &= ~m;            n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);            if (n == 0) {                n = 1;            }            if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {                goto done;            }            map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);            for (n = 1; n < map; n++) {                if (bitmap[n]) {                    goto done;                }            }            ngx_slab_free_pages(pool, page, 1);            goto done;        }        goto chunk_already_free;    case NGX_SLAB_EXACT:        m = (uintptr_t) 1 <<                (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);        size = ngx_slab_exact_size;        if ((uintptr_t) p & (size - 1)) {            goto wrong_chunk;        }        if (slab & m) {            if (slab == NGX_SLAB_BUSY) {                slots = (ngx_slab_page_t *)                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));                slot = ngx_slab_exact_shift - pool->min_shift;                page->next = slots[slot].next;                slots[slot].next = page;                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;                page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;            }            page->slab &= ~m;            if (page->slab) {                goto done;            }            ngx_slab_free_pages(pool, page, 1);            goto done;        }        goto chunk_already_free;    case NGX_SLAB_BIG:        shift = slab & NGX_SLAB_SHIFT_MASK;        size = 1 << shift;        if ((uintptr_t) p & (size - 1)) {            goto wrong_chunk;        }        m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)                              + NGX_SLAB_MAP_SHIFT);        if (slab & m) {            if (page->next == NULL) {                slots = (ngx_slab_page_t *)                                   ((u_char *) pool + sizeof(ngx_slab_pool_t));                slot = shift - pool->min_shift;                page->next = slots[slot].next;                slots[slot].next = page;                page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;                page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;            }            page->slab &= ~m;            if (page->slab & NGX_SLAB_MAP_MASK) {                goto done;            }            ngx_slab_free_pages(pool, page, 1);            goto done;        }        goto chunk_already_free;    case NGX_SLAB_PAGE:        if ((uintptr_t) p & (ngx_pagesize - 1)) {            goto wrong_chunk;        }        if (slab == NGX_SLAB_PAGE_FREE) {            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,                          "ngx_slab_free(): page is already free");            goto fail;        }        if (slab == NGX_SLAB_PAGE_BUSY) {            ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,                          "ngx_slab_free(): pointer to wrong page");            goto fail;        }        n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;        size = slab & ~NGX_SLAB_PAGE_START;        ngx_slab_free_pages(pool, &pool->pages[n], size);        size <<= ngx_pagesize_shift;        goto done;    }    /* not reached */    return;done:    ngx_slab_junk(p, size);    return;wrong_chunk:    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,                      "ngx_slab_free(): pointer to wrong chunk");    goto fail;chunk_already_free:    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,                      "ngx_slab_free(): chunk is already free");fail:    return;}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[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;#if (NGX_DEBUG)            page->next = NULL;            page->prev = NGX_SLAB_PAGE;#endif            if (--pages == 0) {                return page;            }            for (p = page + 1; pages; pages--) {                p->slab = NGX_SLAB_PAGE_BUSY;#if (NGX_DEBUG)                p->next = NULL;                p->prev = NGX_SLAB_PAGE;#endif                p++;            }            return page;        }    }    ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM,                      "ngx_slab_alloc(): failed");    return NULL;}static voidngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,    ngx_uint_t pages){    ngx_slab_page_t  *prev;    page->slab = pages--;    if (pages) {        ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));    }    if (page->next) {        prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK);        prev->next = page->next;        page->next->prev = page->prev;    }    page->prev = (uintptr_t) &pool->free;    page->next = pool->free.next;    page->next->prev = (uintptr_t) page;    pool->free.next = page;}

⌨️ 快捷键说明

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