many bug fixes and ngx_slab_alloc_locked()/ngx_slab_free_locked()

This commit is contained in:
Igor Sysoev 2007-01-02 23:10:42 +00:00
parent dcec2fa8c9
commit c33efcd10a
2 changed files with 50 additions and 26 deletions

View File

@ -147,15 +147,32 @@ ngx_slab_init(ngx_slab_pool_t *pool)
void * void *
ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size) 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; size_t s;
uintptr_t p, n, m, mask, *bitmap; uintptr_t p, n, m, mask, *bitmap;
ngx_uint_t i, slot, shift, map; ngx_uint_t i, slot, shift, map;
ngx_slab_page_t *page, *prev, *slots; 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) page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1)
>> ngx_pagesize_shift); >> ngx_pagesize_shift);
if (page) { if (page) {
@ -186,14 +203,9 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t)); slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));
page = slots[slot].next; 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 (page->next != page) {
if (size < ngx_slab_exact_size) { if (shift < ngx_slab_exact_shift) {
do { do {
p = (page - pool->pages) << ngx_pagesize_shift; p = (page - pool->pages) << ngx_pagesize_shift;
@ -212,7 +224,9 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
} }
bitmap[n] |= m; bitmap[n] |= m;
i <<= shift;
i = ((n * sizeof(uintptr_t) * 8) << shift)
+ (i << shift);
if (bitmap[n] == NGX_SLAB_BUSY) { if (bitmap[n] == NGX_SLAB_BUSY) {
for (n = n + 1; n < map; n++) { for (n = n + 1; n < map; n++) {
@ -243,7 +257,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
} while (page); } while (page);
} else if (size == ngx_slab_exact_size) { } else if (shift == ngx_slab_exact_shift) {
do { do {
if (page->slab != NGX_SLAB_BUSY) { if (page->slab != NGX_SLAB_BUSY) {
@ -277,7 +291,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
} while (page); } while (page);
} else { /* size < ngx_pagesize */ } else { /* shift > ngx_slab_exact_shift */
n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK); n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
n = 1 << n; n = 1 << n;
@ -324,7 +338,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
page = ngx_slab_alloc_pages(pool, 1); page = ngx_slab_alloc_pages(pool, 1);
if (page) { if (page) {
if (size < ngx_slab_exact_size) { if (shift < ngx_slab_exact_shift) {
p = (page - pool->pages) << ngx_pagesize_shift; p = (page - pool->pages) << ngx_pagesize_shift;
bitmap = (uintptr_t *) (pool->start + p); bitmap = (uintptr_t *) (pool->start + p);
@ -354,7 +368,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
goto done; goto done;
} else if (size == ngx_slab_exact_size) { } else if (shift == ngx_slab_exact_shift) {
page->slab = 1; page->slab = 1;
page->next = &slots[slot]; page->next = &slots[slot];
@ -367,7 +381,7 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
goto done; goto done;
} else { /* size < ngx_pagesize */ } else { /* shift > ngx_slab_exact_shift */
page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift; page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
page->next = &slots[slot]; page->next = &slots[slot];
@ -386,8 +400,6 @@ ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
done: done:
ngx_shmtx_unlock(&pool->mutex);
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p); ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);
return (void *) p; return (void *) p;
@ -396,6 +408,17 @@ done:
void void
ngx_slab_free(ngx_slab_pool_t *pool, void *p) 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; size_t size;
uintptr_t slab, *bitmap; uintptr_t slab, *bitmap;
@ -404,8 +427,6 @@ ngx_slab_free(ngx_slab_pool_t *pool, void *p)
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p); 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) { if ((u_char *) p < pool->start || (u_char *) p > pool->end) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
"ngx_slab_free(): outside of pool"); "ngx_slab_free(): outside of pool");
@ -584,8 +605,6 @@ done:
ngx_slab_junk(p, size); ngx_slab_junk(p, size);
ngx_shmtx_unlock(&pool->mutex);
return; return;
wrong_chunk: wrong_chunk:
@ -602,8 +621,6 @@ chunk_already_free:
fail: fail:
ngx_shmtx_unlock(&pool->mutex);
return; return;
} }
@ -658,6 +675,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM, ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM,
"ngx_slab_alloc(): failed"); "ngx_slab_alloc(): failed");
return NULL; return NULL;
} }
@ -674,12 +692,16 @@ ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t)); ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));
} }
prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK); if (page->next) {
prev->next = 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 = pool->free.next;
pool->free.next = page;
page->prev = page->next->prev;
page->next->prev = (uintptr_t) page; page->next->prev = (uintptr_t) page;
pool->free.next = page;
} }

View File

@ -39,7 +39,9 @@ typedef struct {
void ngx_slab_init(ngx_slab_pool_t *pool); 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(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(ngx_slab_pool_t *pool, void *p);
void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p);
#endif /* _NGX_SLAB_H_INCLUDED_ */ #endif /* _NGX_SLAB_H_INCLUDED_ */