[nginx] Slab: simplified allocation from slots.

Ruslan Ermilov ru at nginx.com
Wed Dec 7 19:28:00 UTC 2016


details:   http://hg.nginx.org/nginx/rev/d0404c9a7675
branches:  
changeset: 6826:d0404c9a7675
user:      Ruslan Ermilov <ru at nginx.com>
date:      Wed Dec 07 22:25:37 2016 +0300
description:
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:

 src/core/ngx_slab.c |  150 ++++++++++++++++++++++-----------------------------
 1 files changed, 66 insertions(+), 84 deletions(-)

diffs (193 lines):

diff -r f6beb55792de -r d0404c9a7675 src/core/ngx_slab.c
--- a/src/core/ngx_slab.c	Wed Dec 07 22:25:37 2016 +0300
+++ b/src/core/ngx_slab.c	Wed Dec 07 22:25:37 2016 +0300
@@ -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;
-                            }
+            map = (1 << (ngx_pagesize_shift - shift))
+                      / (sizeof(uintptr_t) * 8);
 
-                            p = (uintptr_t) bitmap + i;
-
-                            goto done;
-                        }
-                    }
-                }
+            for (n = 0; n < map; n++) {
 
-                page = page->next;
-
-            } 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;
 
-                        if (page->slab == NGX_SLAB_BUSY) {
+                        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;
+
+                                    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) {
 
-            } 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 *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;
 
-            } while (page);
+                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;
+            }
         }
+
+        ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_alloc(): page is busy");
+        ngx_debug_point();
     }
 
     page = ngx_slab_alloc_pages(pool, 1);


More information about the nginx-devel mailing list