Annotation of embedaddon/nginx/src/core/ngx_slab.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * Copyright (C) Igor Sysoev
! 4: * Copyright (C) Nginx, Inc.
! 5: */
! 6:
! 7: #include <ngx_config.h>
! 8: #include <ngx_core.h>
! 9:
! 10:
! 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
! 16:
! 17: #if (NGX_PTR_SIZE == 4)
! 18:
! 19: #define NGX_SLAB_PAGE_FREE 0
! 20: #define NGX_SLAB_PAGE_BUSY 0xffffffff
! 21: #define NGX_SLAB_PAGE_START 0x80000000
! 22:
! 23: #define NGX_SLAB_SHIFT_MASK 0x0000000f
! 24: #define NGX_SLAB_MAP_MASK 0xffff0000
! 25: #define NGX_SLAB_MAP_SHIFT 16
! 26:
! 27: #define NGX_SLAB_BUSY 0xffffffff
! 28:
! 29: #else /* (NGX_PTR_SIZE == 8) */
! 30:
! 31: #define NGX_SLAB_PAGE_FREE 0
! 32: #define NGX_SLAB_PAGE_BUSY 0xffffffffffffffff
! 33: #define NGX_SLAB_PAGE_START 0x8000000000000000
! 34:
! 35: #define NGX_SLAB_SHIFT_MASK 0x000000000000000f
! 36: #define NGX_SLAB_MAP_MASK 0xffffffff00000000
! 37: #define NGX_SLAB_MAP_SHIFT 32
! 38:
! 39: #define NGX_SLAB_BUSY 0xffffffffffffffff
! 40:
! 41: #endif
! 42:
! 43:
! 44: #if (NGX_DEBUG_MALLOC)
! 45:
! 46: #define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size)
! 47:
! 48: #elif (NGX_HAVE_DEBUG_MALLOC)
! 49:
! 50: #define ngx_slab_junk(p, size) \
! 51: if (ngx_debug_malloc) ngx_memset(p, 0xA5, size)
! 52:
! 53: #else
! 54:
! 55: #define ngx_slab_junk(p, size)
! 56:
! 57: #endif
! 58:
! 59: static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
! 60: ngx_uint_t pages);
! 61: static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
! 62: ngx_uint_t pages);
! 63: static void ngx_slab_error(ngx_slab_pool_t *pool, ngx_uint_t level,
! 64: char *text);
! 65:
! 66:
! 67: static ngx_uint_t ngx_slab_max_size;
! 68: static ngx_uint_t ngx_slab_exact_size;
! 69: static ngx_uint_t ngx_slab_exact_shift;
! 70:
! 71:
! 72: void
! 73: ngx_slab_init(ngx_slab_pool_t *pool)
! 74: {
! 75: u_char *p;
! 76: size_t size;
! 77: ngx_int_t m;
! 78: ngx_uint_t i, n, pages;
! 79: ngx_slab_page_t *slots;
! 80:
! 81: /* STUB */
! 82: if (ngx_slab_max_size == 0) {
! 83: ngx_slab_max_size = ngx_pagesize / 2;
! 84: ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));
! 85: for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {
! 86: /* void */
! 87: }
! 88: }
! 89: /**/
! 90:
! 91: pool->min_size = 1 << pool->min_shift;
! 92:
! 93: p = (u_char *) pool + sizeof(ngx_slab_pool_t);
! 94: size = pool->end - p;
! 95:
! 96: ngx_slab_junk(p, size);
! 97:
! 98: slots = (ngx_slab_page_t *) p;
! 99: n = ngx_pagesize_shift - pool->min_shift;
! 100:
! 101: for (i = 0; i < n; i++) {
! 102: slots[i].slab = 0;
! 103: slots[i].next = &slots[i];
! 104: slots[i].prev = 0;
! 105: }
! 106:
! 107: p += n * sizeof(ngx_slab_page_t);
! 108:
! 109: pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
! 110:
! 111: ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
! 112:
! 113: pool->pages = (ngx_slab_page_t *) p;
! 114:
! 115: pool->free.prev = 0;
! 116: pool->free.next = (ngx_slab_page_t *) p;
! 117:
! 118: pool->pages->slab = pages;
! 119: pool->pages->next = &pool->free;
! 120: pool->pages->prev = (uintptr_t) &pool->free;
! 121:
! 122: pool->start = (u_char *)
! 123: ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
! 124: ngx_pagesize);
! 125:
! 126: m = pages - (pool->end - pool->start) / ngx_pagesize;
! 127: if (m > 0) {
! 128: pages -= m;
! 129: pool->pages->slab = pages;
! 130: }
! 131:
! 132: pool->log_ctx = &pool->zero;
! 133: pool->zero = '\0';
! 134: }
! 135:
! 136:
! 137: void *
! 138: ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
! 139: {
! 140: void *p;
! 141:
! 142: ngx_shmtx_lock(&pool->mutex);
! 143:
! 144: p = ngx_slab_alloc_locked(pool, size);
! 145:
! 146: ngx_shmtx_unlock(&pool->mutex);
! 147:
! 148: return p;
! 149: }
! 150:
! 151:
! 152: void *
! 153: ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
! 154: {
! 155: size_t s;
! 156: uintptr_t p, n, m, mask, *bitmap;
! 157: ngx_uint_t i, slot, shift, map;
! 158: ngx_slab_page_t *page, *prev, *slots;
! 159:
! 160: if (size >= ngx_slab_max_size) {
! 161:
! 162: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
! 163: "slab alloc: %uz", size);
! 164:
! 165: page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift)
! 166: + ((size % ngx_pagesize) ? 1 : 0));
! 167: if (page) {
! 168: p = (page - pool->pages) << ngx_pagesize_shift;
! 169: p += (uintptr_t) pool->start;
! 170:
! 171: } else {
! 172: p = 0;
! 173: }
! 174:
! 175: goto done;
! 176: }
! 177:
! 178: if (size > pool->min_size) {
! 179: shift = 1;
! 180: for (s = size - 1; s >>= 1; shift++) { /* void */ }
! 181: slot = shift - pool->min_shift;
! 182:
! 183: } else {
! 184: size = pool->min_size;
! 185: shift = pool->min_shift;
! 186: slot = 0;
! 187: }
! 188:
! 189: ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
! 190: "slab alloc: %uz slot: %ui", size, slot);
! 191:
! 192: slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));
! 193: page = slots[slot].next;
! 194:
! 195: if (page->next != page) {
! 196:
! 197: if (shift < ngx_slab_exact_shift) {
! 198:
! 199: do {
! 200: p = (page - pool->pages) << ngx_pagesize_shift;
! 201: bitmap = (uintptr_t *) (pool->start + p);
! 202:
! 203: map = (1 << (ngx_pagesize_shift - shift))
! 204: / (sizeof(uintptr_t) * 8);
! 205:
! 206: for (n = 0; n < map; n++) {
! 207:
! 208: if (bitmap[n] != NGX_SLAB_BUSY) {
! 209:
! 210: for (m = 1, i = 0; m; m <<= 1, i++) {
! 211: if ((bitmap[n] & m)) {
! 212: continue;
! 213: }
! 214:
! 215: bitmap[n] |= m;
! 216:
! 217: i = ((n * sizeof(uintptr_t) * 8) << shift)
! 218: + (i << shift);
! 219:
! 220: if (bitmap[n] == NGX_SLAB_BUSY) {
! 221: for (n = n + 1; n < map; n++) {
! 222: if (bitmap[n] != NGX_SLAB_BUSY) {
! 223: p = (uintptr_t) bitmap + i;
! 224:
! 225: goto done;
! 226: }
! 227: }
! 228:
! 229: prev = (ngx_slab_page_t *)
! 230: (page->prev & ~NGX_SLAB_PAGE_MASK);
! 231: prev->next = page->next;
! 232: page->next->prev = page->prev;
! 233:
! 234: page->next = NULL;
! 235: page->prev = NGX_SLAB_SMALL;
! 236: }
! 237:
! 238: p = (uintptr_t) bitmap + i;
! 239:
! 240: goto done;
! 241: }
! 242: }
! 243: }
! 244:
! 245: page = page->next;
! 246:
! 247: } while (page);
! 248:
! 249: } else if (shift == ngx_slab_exact_shift) {
! 250:
! 251: do {
! 252: if (page->slab != NGX_SLAB_BUSY) {
! 253:
! 254: for (m = 1, i = 0; m; m <<= 1, i++) {
! 255: if ((page->slab & m)) {
! 256: continue;
! 257: }
! 258:
! 259: page->slab |= m;
! 260:
! 261: if (page->slab == NGX_SLAB_BUSY) {
! 262: prev = (ngx_slab_page_t *)
! 263: (page->prev & ~NGX_SLAB_PAGE_MASK);
! 264: prev->next = page->next;
! 265: page->next->prev = page->prev;
! 266:
! 267: page->next = NULL;
! 268: page->prev = NGX_SLAB_EXACT;
! 269: }
! 270:
! 271: p = (page - pool->pages) << ngx_pagesize_shift;
! 272: p += i << shift;
! 273: p += (uintptr_t) pool->start;
! 274:
! 275: goto done;
! 276: }
! 277: }
! 278:
! 279: page = page->next;
! 280:
! 281: } while (page);
! 282:
! 283: } else { /* shift > ngx_slab_exact_shift */
! 284:
! 285: n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
! 286: n = 1 << n;
! 287: n = ((uintptr_t) 1 << n) - 1;
! 288: mask = n << NGX_SLAB_MAP_SHIFT;
! 289:
! 290: do {
! 291: if ((page->slab & NGX_SLAB_MAP_MASK) != mask) {
! 292:
! 293: for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
! 294: m & mask;
! 295: m <<= 1, i++)
! 296: {
! 297: if ((page->slab & m)) {
! 298: continue;
! 299: }
! 300:
! 301: page->slab |= m;
! 302:
! 303: if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
! 304: prev = (ngx_slab_page_t *)
! 305: (page->prev & ~NGX_SLAB_PAGE_MASK);
! 306: prev->next = page->next;
! 307: page->next->prev = page->prev;
! 308:
! 309: page->next = NULL;
! 310: page->prev = NGX_SLAB_BIG;
! 311: }
! 312:
! 313: p = (page - pool->pages) << ngx_pagesize_shift;
! 314: p += i << shift;
! 315: p += (uintptr_t) pool->start;
! 316:
! 317: goto done;
! 318: }
! 319: }
! 320:
! 321: page = page->next;
! 322:
! 323: } while (page);
! 324: }
! 325: }
! 326:
! 327: page = ngx_slab_alloc_pages(pool, 1);
! 328:
! 329: if (page) {
! 330: if (shift < ngx_slab_exact_shift) {
! 331: p = (page - pool->pages) << ngx_pagesize_shift;
! 332: bitmap = (uintptr_t *) (pool->start + p);
! 333:
! 334: s = 1 << shift;
! 335: n = (1 << (ngx_pagesize_shift - shift)) / 8 / s;
! 336:
! 337: if (n == 0) {
! 338: n = 1;
! 339: }
! 340:
! 341: bitmap[0] = (2 << n) - 1;
! 342:
! 343: map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
! 344:
! 345: for (i = 1; i < map; i++) {
! 346: bitmap[i] = 0;
! 347: }
! 348:
! 349: page->slab = shift;
! 350: page->next = &slots[slot];
! 351: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
! 352:
! 353: slots[slot].next = page;
! 354:
! 355: p = ((page - pool->pages) << ngx_pagesize_shift) + s * n;
! 356: p += (uintptr_t) pool->start;
! 357:
! 358: goto done;
! 359:
! 360: } else if (shift == ngx_slab_exact_shift) {
! 361:
! 362: page->slab = 1;
! 363: page->next = &slots[slot];
! 364: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
! 365:
! 366: slots[slot].next = page;
! 367:
! 368: p = (page - pool->pages) << ngx_pagesize_shift;
! 369: p += (uintptr_t) pool->start;
! 370:
! 371: goto done;
! 372:
! 373: } else { /* shift > ngx_slab_exact_shift */
! 374:
! 375: page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
! 376: page->next = &slots[slot];
! 377: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
! 378:
! 379: slots[slot].next = page;
! 380:
! 381: p = (page - pool->pages) << ngx_pagesize_shift;
! 382: p += (uintptr_t) pool->start;
! 383:
! 384: goto done;
! 385: }
! 386: }
! 387:
! 388: p = 0;
! 389:
! 390: done:
! 391:
! 392: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);
! 393:
! 394: return (void *) p;
! 395: }
! 396:
! 397:
! 398: void
! 399: ngx_slab_free(ngx_slab_pool_t *pool, void *p)
! 400: {
! 401: ngx_shmtx_lock(&pool->mutex);
! 402:
! 403: ngx_slab_free_locked(pool, p);
! 404:
! 405: ngx_shmtx_unlock(&pool->mutex);
! 406: }
! 407:
! 408:
! 409: void
! 410: ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
! 411: {
! 412: size_t size;
! 413: uintptr_t slab, m, *bitmap;
! 414: ngx_uint_t n, type, slot, shift, map;
! 415: ngx_slab_page_t *slots, *page;
! 416:
! 417: ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
! 418:
! 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");
! 421: goto fail;
! 422: }
! 423:
! 424: n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
! 425: page = &pool->pages[n];
! 426: slab = page->slab;
! 427: type = page->prev & NGX_SLAB_PAGE_MASK;
! 428:
! 429: switch (type) {
! 430:
! 431: case NGX_SLAB_SMALL:
! 432:
! 433: shift = slab & NGX_SLAB_SHIFT_MASK;
! 434: size = 1 << shift;
! 435:
! 436: if ((uintptr_t) p & (size - 1)) {
! 437: goto wrong_chunk;
! 438: }
! 439:
! 440: n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
! 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));
! 444:
! 445: if (bitmap[n] & m) {
! 446:
! 447: if (page->next == NULL) {
! 448: slots = (ngx_slab_page_t *)
! 449: ((u_char *) pool + sizeof(ngx_slab_pool_t));
! 450: slot = shift - pool->min_shift;
! 451:
! 452: page->next = slots[slot].next;
! 453: slots[slot].next = page;
! 454:
! 455: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
! 456: page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;
! 457: }
! 458:
! 459: bitmap[n] &= ~m;
! 460:
! 461: n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);
! 462:
! 463: if (n == 0) {
! 464: n = 1;
! 465: }
! 466:
! 467: if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
! 468: goto done;
! 469: }
! 470:
! 471: map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
! 472:
! 473: for (n = 1; n < map; n++) {
! 474: if (bitmap[n]) {
! 475: goto done;
! 476: }
! 477: }
! 478:
! 479: ngx_slab_free_pages(pool, page, 1);
! 480:
! 481: goto done;
! 482: }
! 483:
! 484: goto chunk_already_free;
! 485:
! 486: case NGX_SLAB_EXACT:
! 487:
! 488: m = (uintptr_t) 1 <<
! 489: (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
! 490: size = ngx_slab_exact_size;
! 491:
! 492: if ((uintptr_t) p & (size - 1)) {
! 493: goto wrong_chunk;
! 494: }
! 495:
! 496: if (slab & m) {
! 497: if (slab == NGX_SLAB_BUSY) {
! 498: slots = (ngx_slab_page_t *)
! 499: ((u_char *) pool + sizeof(ngx_slab_pool_t));
! 500: slot = ngx_slab_exact_shift - pool->min_shift;
! 501:
! 502: page->next = slots[slot].next;
! 503: slots[slot].next = page;
! 504:
! 505: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
! 506: page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;
! 507: }
! 508:
! 509: page->slab &= ~m;
! 510:
! 511: if (page->slab) {
! 512: goto done;
! 513: }
! 514:
! 515: ngx_slab_free_pages(pool, page, 1);
! 516:
! 517: goto done;
! 518: }
! 519:
! 520: goto chunk_already_free;
! 521:
! 522: case NGX_SLAB_BIG:
! 523:
! 524: shift = slab & NGX_SLAB_SHIFT_MASK;
! 525: size = 1 << shift;
! 526:
! 527: if ((uintptr_t) p & (size - 1)) {
! 528: goto wrong_chunk;
! 529: }
! 530:
! 531: m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
! 532: + NGX_SLAB_MAP_SHIFT);
! 533:
! 534: if (slab & m) {
! 535:
! 536: if (page->next == NULL) {
! 537: slots = (ngx_slab_page_t *)
! 538: ((u_char *) pool + sizeof(ngx_slab_pool_t));
! 539: slot = shift - pool->min_shift;
! 540:
! 541: page->next = slots[slot].next;
! 542: slots[slot].next = page;
! 543:
! 544: page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
! 545: page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;
! 546: }
! 547:
! 548: page->slab &= ~m;
! 549:
! 550: if (page->slab & NGX_SLAB_MAP_MASK) {
! 551: goto done;
! 552: }
! 553:
! 554: ngx_slab_free_pages(pool, page, 1);
! 555:
! 556: goto done;
! 557: }
! 558:
! 559: goto chunk_already_free;
! 560:
! 561: case NGX_SLAB_PAGE:
! 562:
! 563: if ((uintptr_t) p & (ngx_pagesize - 1)) {
! 564: goto wrong_chunk;
! 565: }
! 566:
! 567: if (slab == NGX_SLAB_PAGE_FREE) {
! 568: ngx_slab_error(pool, NGX_LOG_ALERT,
! 569: "ngx_slab_free(): page is already free");
! 570: goto fail;
! 571: }
! 572:
! 573: if (slab == NGX_SLAB_PAGE_BUSY) {
! 574: ngx_slab_error(pool, NGX_LOG_ALERT,
! 575: "ngx_slab_free(): pointer to wrong page");
! 576: goto fail;
! 577: }
! 578:
! 579: n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
! 580: size = slab & ~NGX_SLAB_PAGE_START;
! 581:
! 582: ngx_slab_free_pages(pool, &pool->pages[n], size);
! 583:
! 584: ngx_slab_junk(p, size << ngx_pagesize_shift);
! 585:
! 586: return;
! 587: }
! 588:
! 589: /* not reached */
! 590:
! 591: return;
! 592:
! 593: done:
! 594:
! 595: ngx_slab_junk(p, size);
! 596:
! 597: return;
! 598:
! 599: wrong_chunk:
! 600:
! 601: ngx_slab_error(pool, NGX_LOG_ALERT,
! 602: "ngx_slab_free(): pointer to wrong chunk");
! 603:
! 604: goto fail;
! 605:
! 606: chunk_already_free:
! 607:
! 608: ngx_slab_error(pool, NGX_LOG_ALERT,
! 609: "ngx_slab_free(): chunk is already free");
! 610:
! 611: fail:
! 612:
! 613: return;
! 614: }
! 615:
! 616:
! 617: static ngx_slab_page_t *
! 618: ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
! 619: {
! 620: ngx_slab_page_t *page, *p;
! 621:
! 622: for (page = pool->free.next; page != &pool->free; page = page->next) {
! 623:
! 624: if (page->slab >= pages) {
! 625:
! 626: if (page->slab > pages) {
! 627: page[pages].slab = page->slab - pages;
! 628: page[pages].next = page->next;
! 629: page[pages].prev = page->prev;
! 630:
! 631: p = (ngx_slab_page_t *) page->prev;
! 632: p->next = &page[pages];
! 633: page->next->prev = (uintptr_t) &page[pages];
! 634:
! 635: } else {
! 636: p = (ngx_slab_page_t *) page->prev;
! 637: p->next = page->next;
! 638: page->next->prev = page->prev;
! 639: }
! 640:
! 641: page->slab = pages | NGX_SLAB_PAGE_START;
! 642: page->next = NULL;
! 643: page->prev = NGX_SLAB_PAGE;
! 644:
! 645: if (--pages == 0) {
! 646: return page;
! 647: }
! 648:
! 649: for (p = page + 1; pages; pages--) {
! 650: p->slab = NGX_SLAB_PAGE_BUSY;
! 651: p->next = NULL;
! 652: p->prev = NGX_SLAB_PAGE;
! 653: p++;
! 654: }
! 655:
! 656: return page;
! 657: }
! 658: }
! 659:
! 660: ngx_slab_error(pool, NGX_LOG_CRIT, "ngx_slab_alloc() failed: no memory");
! 661:
! 662: return NULL;
! 663: }
! 664:
! 665:
! 666: static void
! 667: ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
! 668: ngx_uint_t pages)
! 669: {
! 670: ngx_slab_page_t *prev;
! 671:
! 672: page->slab = pages--;
! 673:
! 674: if (pages) {
! 675: ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));
! 676: }
! 677:
! 678: if (page->next) {
! 679: prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK);
! 680: prev->next = page->next;
! 681: page->next->prev = page->prev;
! 682: }
! 683:
! 684: page->prev = (uintptr_t) &pool->free;
! 685: page->next = pool->free.next;
! 686:
! 687: page->next->prev = (uintptr_t) page;
! 688:
! 689: pool->free.next = page;
! 690: }
! 691:
! 692:
! 693: static void
! 694: ngx_slab_error(ngx_slab_pool_t *pool, ngx_uint_t level, char *text)
! 695: {
! 696: ngx_log_error(level, ngx_cycle->log, 0, "%s%s", text, pool->log_ctx);
! 697: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>