# HG changeset patch # User Igor Sysoev # Date 1167779442 0 # Node ID 715336c243e137c6010c81463a9344b85f113021 # Parent 2e3754f376060d962befce1fa7b0de45233ab817 many bug fixes and ngx_slab_alloc_locked()/ngx_slab_free_locked() diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c --- a/src/core/ngx_slab.c +++ b/src/core/ngx_slab.c @@ -148,14 +148,31 @@ ngx_slab_init(ngx_slab_pool_t *pool) 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; - ngx_shmtx_lock(&pool->mutex); + if (size >= ngx_slab_max_size) { - 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) { @@ -186,14 +203,9 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t)); page = slots[slot].next; -#if 0 - ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, - "slab alloc: page %p next: %p", page, page->next); -#endif - if (page->next != page) { - if (size < ngx_slab_exact_size) { + if (shift < ngx_slab_exact_shift) { do { p = (page - pool->pages) << ngx_pagesize_shift; @@ -212,7 +224,9 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si } bitmap[n] |= m; - i <<= shift; + + i = ((n * sizeof(uintptr_t) * 8) << shift) + + (i << shift); if (bitmap[n] == NGX_SLAB_BUSY) { for (n = n + 1; n < map; n++) { @@ -243,7 +257,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si } while (page); - } else if (size == ngx_slab_exact_size) { + } else if (shift == ngx_slab_exact_shift) { do { if (page->slab != NGX_SLAB_BUSY) { @@ -277,7 +291,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si } while (page); - } else { /* size < ngx_pagesize */ + } else { /* shift > ngx_slab_exact_shift */ n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK); n = 1 << n; @@ -324,7 +338,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si page = ngx_slab_alloc_pages(pool, 1); if (page) { - if (size < ngx_slab_exact_size) { + if (shift < ngx_slab_exact_shift) { p = (page - pool->pages) << ngx_pagesize_shift; bitmap = (uintptr_t *) (pool->start + p); @@ -354,7 +368,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si goto done; - } else if (size == ngx_slab_exact_size) { + } else if (shift == ngx_slab_exact_shift) { page->slab = 1; page->next = &slots[slot]; @@ -367,7 +381,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si goto done; - } else { /* size < ngx_pagesize */ + } else { /* shift > ngx_slab_exact_shift */ page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift; page->next = &slots[slot]; @@ -386,8 +400,6 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, si done: - ngx_shmtx_unlock(&pool->mutex); - ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p); return (void *) p; @@ -397,6 +409,17 @@ done: void ngx_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); +} + + +void +ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p) +{ size_t size; uintptr_t slab, *bitmap; ngx_uint_t n, m, type, slot, shift, map; @@ -404,8 +427,6 @@ ngx_slab_free(ngx_slab_pool_t *pool, voi ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p); - ngx_shmtx_lock(&pool->mutex); - 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"); @@ -584,8 +605,6 @@ done: ngx_slab_junk(p, size); - ngx_shmtx_unlock(&pool->mutex); - return; wrong_chunk: @@ -602,8 +621,6 @@ chunk_already_free: fail: - ngx_shmtx_unlock(&pool->mutex); - return; } @@ -658,6 +675,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *po ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM, "ngx_slab_alloc(): failed"); + return NULL; } @@ -674,12 +692,16 @@ ngx_slab_free_pages(ngx_slab_pool_t *poo ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t)); } - prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK); - prev->next = page->next; + 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; - - page->prev = page->next->prev; - page->next->prev = (uintptr_t) page; } diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h --- a/src/core/ngx_slab.h +++ b/src/core/ngx_slab.h @@ -39,7 +39,9 @@ typedef struct { void ngx_slab_init(ngx_slab_pool_t *pool); void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size); +void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size); void ngx_slab_free(ngx_slab_pool_t *pool, void *p); +void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p); #endif /* _NGX_SLAB_H_INCLUDED_ */