# HG changeset patch # User Ruslan Ermilov # Date 1481138737 -10800 # Node ID d0404c9a7675a3d8257d6a1fac888a7d1e121366 # Parent f6beb55792de5f5921d2bcd9de5ffe4eca4849e4 Slab: simplified allocation from slots. Removed code that would cause an endless loop, and removed condition check that is always false. The first page in the slot list is guaranteed to satisfy an allocation. 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 @@ -215,84 +215,71 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p if (shift < ngx_slab_exact_shift) { - do { - bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - - 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; + bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page); - goto done; - } - } - - prev = ngx_slab_page_prev(page); - prev->next = page->next; - page->next->prev = page->prev; - - page->next = NULL; - page->prev = NGX_SLAB_SMALL; - } - - p = (uintptr_t) bitmap + i; + map = (1 << (ngx_pagesize_shift - shift)) + / (sizeof(uintptr_t) * 8); - goto done; - } - } - } - - page = page->next; + for (n = 0; n < map; n++) { - } while (page); - - } else if (shift == ngx_slab_exact_shift) { - - do { - if (page->slab != NGX_SLAB_BUSY) { + if (bitmap[n] != NGX_SLAB_BUSY) { for (m = 1, i = 0; m; m <<= 1, i++) { - if (page->slab & m) { + if (bitmap[n] & m) { continue; } - page->slab |= m; + bitmap[n] |= m; + + i = ((n * sizeof(uintptr_t) * 8) << shift) + + (i << shift); - if (page->slab == NGX_SLAB_BUSY) { + 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_prev(page); prev->next = page->next; page->next->prev = page->prev; page->next = NULL; - page->prev = NGX_SLAB_EXACT; + page->prev = NGX_SLAB_SMALL; } - p = ngx_slab_page_addr(pool, page) + (i << shift); + p = (uintptr_t) bitmap + i; goto done; } } + } - page = page->next; + } else if (shift == ngx_slab_exact_shift) { + + for (m = 1, i = 0; m; m <<= 1, i++) { + if (page->slab & m) { + continue; + } + + page->slab |= m; - } while (page); + if (page->slab == NGX_SLAB_BUSY) { + prev = ngx_slab_page_prev(page); + prev->next = page->next; + page->next->prev = page->prev; + + page->next = NULL; + page->prev = NGX_SLAB_EXACT; + } + + p = ngx_slab_page_addr(pool, page) + (i << shift); + + goto done; + } } else { /* shift > ngx_slab_exact_shift */ @@ -301,38 +288,33 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *p 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_prev(page); - prev->next = page->next; - page->next->prev = page->prev; - - page->next = NULL; - page->prev = NGX_SLAB_BIG; - } - - p = ngx_slab_page_addr(pool, page) + (i << shift); - - goto done; - } + for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0; + m & mask; + m <<= 1, i++) + { + if (page->slab & m) { + continue; } - page = page->next; + page->slab |= m; + + if ((page->slab & NGX_SLAB_MAP_MASK) == mask) { + prev = ngx_slab_page_prev(page); + prev->next = page->next; + page->next->prev = page->prev; - } while (page); + page->next = NULL; + page->prev = NGX_SLAB_BIG; + } + + p = ngx_slab_page_addr(pool, page) + (i << shift); + + goto done; + } } + + ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy"); + ngx_debug_point(); } page = ngx_slab_alloc_pages(pool, 1);