11 #define NGX_SLAB_PAGE_MASK 3
12 #define NGX_SLAB_PAGE 0
13 #define NGX_SLAB_BIG 1
14 #define NGX_SLAB_EXACT 2
15 #define NGX_SLAB_SMALL 3
17 #if (NGX_PTR_SIZE == 4)
19 #define NGX_SLAB_PAGE_FREE 0
20 #define NGX_SLAB_PAGE_BUSY 0xffffffff
21 #define NGX_SLAB_PAGE_START 0x80000000
23 #define NGX_SLAB_SHIFT_MASK 0x0000000f
24 #define NGX_SLAB_MAP_MASK 0xffff0000
25 #define NGX_SLAB_MAP_SHIFT 16
27 #define NGX_SLAB_BUSY 0xffffffff
31 #define NGX_SLAB_PAGE_FREE 0
32 #define NGX_SLAB_PAGE_BUSY 0xffffffffffffffff
33 #define NGX_SLAB_PAGE_START 0x8000000000000000
35 #define NGX_SLAB_SHIFT_MASK 0x000000000000000f
36 #define NGX_SLAB_MAP_MASK 0xffffffff00000000
37 #define NGX_SLAB_MAP_SHIFT 32
39 #define NGX_SLAB_BUSY 0xffffffffffffffff
44 #if (NGX_DEBUG_MALLOC)
46 #define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size)
48 #elif (NGX_HAVE_DEBUG_MALLOC)
50 #define ngx_slab_junk(p, size) \
51 if (ngx_debug_malloc) ngx_memset(p, 0xA5, size)
55 #define ngx_slab_junk(p, size)
82 if (ngx_slab_max_size == 0) {
84 ngx_slab_exact_size =
ngx_pagesize / (8 *
sizeof(uintptr_t));
85 for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {
101 for (i = 0; i < n; i++) {
103 slots[
i].
next = &slots[
i];
122 pool->
start = (u_char *)
156 uintptr_t p, n, m, mask, *bitmap;
160 if (size >= ngx_slab_max_size) {
163 "slab alloc: %uz", size);
169 p += (uintptr_t) pool->
start;
180 for (s = size - 1; s >>= 1; shift++) { }
190 "slab alloc: %uz slot: %ui", size, slot);
193 page = slots[slot].
next;
195 if (page->
next != page) {
197 if (shift < ngx_slab_exact_shift) {
201 bitmap = (uintptr_t *) (pool->
start + p);
204 / (
sizeof(uintptr_t) * 8);
206 for (n = 0; n < map; n++) {
210 for (m = 1, i = 0; m; m <<= 1, i++) {
211 if ((bitmap[n] & m)) {
217 i = ((n *
sizeof(uintptr_t) * 8) << shift)
221 for (n = n + 1; n < map; n++) {
223 p = (uintptr_t) bitmap + i;
238 p = (uintptr_t) bitmap + i;
249 }
else if (shift == ngx_slab_exact_shift) {
254 for (m = 1, i = 0; m; m <<= 1, i++) {
255 if ((page->
slab & m)) {
273 p += (uintptr_t) pool->
start;
287 n = ((uintptr_t) 1 << n) - 1;
297 if ((page->
slab & m)) {
315 p += (uintptr_t) pool->
start;
327 page = ngx_slab_alloc_pages(pool, 1);
330 if (shift < ngx_slab_exact_shift) {
332 bitmap = (uintptr_t *) (pool->
start + p);
341 bitmap[0] = (2 << n) - 1;
345 for (i = 1; i < map; i++) {
350 page->
next = &slots[slot];
353 slots[slot].
next = page;
356 p += (uintptr_t) pool->
start;
360 }
else if (shift == ngx_slab_exact_shift) {
363 page->
next = &slots[slot];
366 slots[slot].
next = page;
369 p += (uintptr_t) pool->
start;
376 page->
next = &slots[slot];
379 slots[slot].
next = page;
382 p += (uintptr_t) pool->
start;
413 uintptr_t slab, m, *bitmap;
419 if ((u_char *) p < pool->start || (u_char *) p > pool->
end) {
420 ngx_slab_error(pool,
NGX_LOG_ALERT,
"ngx_slab_free(): outside of pool");
425 page = &pool->
pages[n];
436 if ((uintptr_t) p & (size - 1)) {
441 m = (uintptr_t) 1 << (n & (
sizeof(uintptr_t) * 8 - 1));
442 n /= (
sizeof(uintptr_t) * 8);
443 bitmap = (uintptr_t *) ((uintptr_t) p & ~(
ngx_pagesize - 1));
447 if (page->
next == NULL) {
453 slots[slot].
next = page;
467 if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
473 for (n = 1; n < map; n++) {
479 ngx_slab_free_pages(pool, page, 1);
484 goto chunk_already_free;
489 (((uintptr_t) p & (
ngx_pagesize - 1)) >> ngx_slab_exact_shift);
490 size = ngx_slab_exact_size;
492 if ((uintptr_t) p & (size - 1)) {
500 slot = ngx_slab_exact_shift - pool->
min_shift;
503 slots[slot].
next = page;
515 ngx_slab_free_pages(pool, page, 1);
520 goto chunk_already_free;
527 if ((uintptr_t) p & (size - 1)) {
531 m = (uintptr_t) 1 << ((((uintptr_t) p & (
ngx_pagesize - 1)) >> shift)
536 if (page->
next == NULL) {
542 slots[slot].
next = page;
554 ngx_slab_free_pages(pool, page, 1);
559 goto chunk_already_free;
569 "ngx_slab_free(): page is already free");
575 "ngx_slab_free(): pointer to wrong page");
582 ngx_slab_free_pages(pool, &pool->
pages[n], size);
602 "ngx_slab_free(): pointer to wrong chunk");
609 "ngx_slab_free(): chunk is already free");
624 if (page->
slab >= pages) {
626 if (page->
slab > pages) {
627 page[pages].
slab = page->
slab - pages;
632 p->
next = &page[pages];
633 page->
next->
prev = (uintptr_t) &page[pages];
649 for (p = page + 1; pages; pages--) {
660 ngx_slab_error(pool,
NGX_LOG_CRIT,
"ngx_slab_alloc() failed: no memory");
672 page->
slab = pages--;
684 page->
prev = (uintptr_t) &pool->
free;
687 page->
next->
prev = (uintptr_t) page;