aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_slab.c
diff options
context:
space:
mode:
authorRuslan Ermilov <ru@nginx.com>2016-12-07 22:25:37 +0300
committerRuslan Ermilov <ru@nginx.com>2016-12-07 22:25:37 +0300
commit12abb66c4138a9be7463db6aad497844d55aba43 (patch)
treeff7ab111ebb99c8c57202aaba8a21fe22d082aa7 /src/core/ngx_slab.c
parent16de9fc3b52e82d1e2be740be4a1ee9adafb6fbf (diff)
downloadnginx-12abb66c4138a9be7463db6aad497844d55aba43.tar.gz
nginx-12abb66c4138a9be7463db6aad497844d55aba43.zip
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.
Diffstat (limited to 'src/core/ngx_slab.c')
-rw-r--r--src/core/ngx_slab.c140
1 files changed, 61 insertions, 79 deletions
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
index b33f43f8e..c5a68f509 100644
--- a/src/core/ngx_slab.c
+++ b/src/core/ngx_slab.c
@@ -215,84 +215,71 @@ ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
if (shift < ngx_slab_exact_shift) {
- do {
- bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);
+ bitmap = (uintptr_t *) ngx_slab_page_addr(pool, page);
- map = (1 << (ngx_pagesize_shift - shift))
- / (sizeof(uintptr_t) * 8);
+ map = (1 << (ngx_pagesize_shift - shift))
+ / (sizeof(uintptr_t) * 8);
- for (n = 0; n < map; n++) {
+ for (n = 0; n < map; n++) {
- if (bitmap[n] != NGX_SLAB_BUSY) {
+ if (bitmap[n] != NGX_SLAB_BUSY) {
- for (m = 1, i = 0; m; m <<= 1, i++) {
- if (bitmap[n] & m) {
- continue;
- }
+ for (m = 1, i = 0; m; m <<= 1, i++) {
+ if (bitmap[n] & m) {
+ continue;
+ }
- bitmap[n] |= m;
+ bitmap[n] |= m;
- i = ((n * sizeof(uintptr_t) * 8) << shift)
- + (i << shift);
+ 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;
+ 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;
- }
+ 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;
-
- 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_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) {
- } while (page);
+ 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_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 *pool, size_t size)
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;
+ for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
+ m & mask;
+ m <<= 1, i++)
+ {
+ if (page->slab & m) {
+ continue;
+ }
- page->next = NULL;
- page->prev = NGX_SLAB_BIG;
- }
+ page->slab |= m;
- p = ngx_slab_page_addr(pool, page) + (i << shift);
+ if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
+ prev = ngx_slab_page_prev(page);
+ prev->next = page->next;
+ page->next->prev = page->prev;
- goto done;
- }
+ page->next = NULL;
+ page->prev = NGX_SLAB_BIG;
}
- page = page->next;
+ p = ngx_slab_page_addr(pool, page) + (i << shift);
- } while (page);
+ 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);