comparison src/core/ngx_slab.c @ 272:29a6403156b0 NGINX_0_5_6

nginx 0.5.6 *) Change: now the ngx_http_index_module ignores all methods except the GET, HEAD, and POST methods. *) Feature: the ngx_http_limit_zone_module. *) Feature: the $binary_remote_addr variable. *) Feature: the "ssl_session_cache" directives of the ngx_http_ssl_module and ngx_imap_ssl_module. *) Feature: the DELETE method supports recursive removal. *) Bugfix: the byte-ranges were transferred incorrectly if the $r->sendfile() was used.
author Igor Sysoev <http://sysoev.ru>
date Tue, 09 Jan 2007 00:00:00 +0300
parents 0effe91f6083
children 052a7b1d40e5
comparison
equal deleted inserted replaced
271:fcbee7dacf2b 272:29a6403156b0
146 146
147 147
148 void * 148 void *
149 ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size) 149 ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
150 { 150 {
151 void *p;
152
153 ngx_shmtx_lock(&pool->mutex);
154
155 p = ngx_slab_alloc_locked(pool, size);
156
157 ngx_shmtx_unlock(&pool->mutex);
158
159 return p;
160 }
161
162
163 void *
164 ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
165 {
151 size_t s; 166 size_t s;
152 uintptr_t p, n, m, mask, *bitmap; 167 uintptr_t p, n, m, mask, *bitmap;
153 ngx_uint_t i, slot, shift, map; 168 ngx_uint_t i, slot, shift, map;
154 ngx_slab_page_t *page, *prev, *slots; 169 ngx_slab_page_t *page, *prev, *slots;
155 170
156 ngx_shmtx_lock(&pool->mutex);
157
158 if (size >= ngx_slab_max_size) { 171 if (size >= ngx_slab_max_size) {
172
173 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
174 "slab alloc: %uz", size);
175
159 page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1) 176 page = ngx_slab_alloc_pages(pool, (size + ngx_pagesize - 1)
160 >> ngx_pagesize_shift); 177 >> ngx_pagesize_shift);
161 if (page) { 178 if (page) {
162 p = (page - pool->pages) << ngx_pagesize_shift; 179 p = (page - pool->pages) << ngx_pagesize_shift;
163 p += (uintptr_t) pool->start; 180 p += (uintptr_t) pool->start;
184 "slab alloc: %uz slot: %ui", size, slot); 201 "slab alloc: %uz slot: %ui", size, slot);
185 202
186 slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t)); 203 slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));
187 page = slots[slot].next; 204 page = slots[slot].next;
188 205
189 #if 0
190 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
191 "slab alloc: page %p next: %p", page, page->next);
192 #endif
193
194 if (page->next != page) { 206 if (page->next != page) {
195 207
196 if (size < ngx_slab_exact_size) { 208 if (shift < ngx_slab_exact_shift) {
197 209
198 do { 210 do {
199 p = (page - pool->pages) << ngx_pagesize_shift; 211 p = (page - pool->pages) << ngx_pagesize_shift;
200 bitmap = (uintptr_t *) (pool->start + p); 212 bitmap = (uintptr_t *) (pool->start + p);
201 213
210 if ((bitmap[n] & m)) { 222 if ((bitmap[n] & m)) {
211 continue; 223 continue;
212 } 224 }
213 225
214 bitmap[n] |= m; 226 bitmap[n] |= m;
215 i <<= shift; 227
228 i = ((n * sizeof(uintptr_t) * 8) << shift)
229 + (i << shift);
216 230
217 if (bitmap[n] == NGX_SLAB_BUSY) { 231 if (bitmap[n] == NGX_SLAB_BUSY) {
218 for (n = n + 1; n < map; n++) { 232 for (n = n + 1; n < map; n++) {
219 if (bitmap[n] != NGX_SLAB_BUSY) { 233 if (bitmap[n] != NGX_SLAB_BUSY) {
220 p = (uintptr_t) bitmap + i; 234 p = (uintptr_t) bitmap + i;
241 255
242 page = page->next; 256 page = page->next;
243 257
244 } while (page); 258 } while (page);
245 259
246 } else if (size == ngx_slab_exact_size) { 260 } else if (shift == ngx_slab_exact_shift) {
247 261
248 do { 262 do {
249 if (page->slab != NGX_SLAB_BUSY) { 263 if (page->slab != NGX_SLAB_BUSY) {
250 264
251 for (m = 1, i = 0; m; m <<= 1, i++) { 265 for (m = 1, i = 0; m; m <<= 1, i++) {
275 289
276 page = page->next; 290 page = page->next;
277 291
278 } while (page); 292 } while (page);
279 293
280 } else { /* size < ngx_pagesize */ 294 } else { /* shift > ngx_slab_exact_shift */
281 295
282 n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK); 296 n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
283 n = 1 << n; 297 n = 1 << n;
284 n = (1 << n) - 1; 298 n = (1 << n) - 1;
285 mask = n << NGX_SLAB_MAP_SHIFT; 299 mask = n << NGX_SLAB_MAP_SHIFT;
322 } 336 }
323 337
324 page = ngx_slab_alloc_pages(pool, 1); 338 page = ngx_slab_alloc_pages(pool, 1);
325 339
326 if (page) { 340 if (page) {
327 if (size < ngx_slab_exact_size) { 341 if (shift < ngx_slab_exact_shift) {
328 p = (page - pool->pages) << ngx_pagesize_shift; 342 p = (page - pool->pages) << ngx_pagesize_shift;
329 bitmap = (uintptr_t *) (pool->start + p); 343 bitmap = (uintptr_t *) (pool->start + p);
330 344
331 s = 1 << shift; 345 s = 1 << shift;
332 n = (1 << (ngx_pagesize_shift - shift)) / 8 / s; 346 n = (1 << (ngx_pagesize_shift - shift)) / 8 / s;
352 p = ((page - pool->pages) << ngx_pagesize_shift) + s * n; 366 p = ((page - pool->pages) << ngx_pagesize_shift) + s * n;
353 p += (uintptr_t) pool->start; 367 p += (uintptr_t) pool->start;
354 368
355 goto done; 369 goto done;
356 370
357 } else if (size == ngx_slab_exact_size) { 371 } else if (shift == ngx_slab_exact_shift) {
358 372
359 page->slab = 1; 373 page->slab = 1;
360 page->next = &slots[slot]; 374 page->next = &slots[slot];
361 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT; 375 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
362 376
365 p = (page - pool->pages) << ngx_pagesize_shift; 379 p = (page - pool->pages) << ngx_pagesize_shift;
366 p += (uintptr_t) pool->start; 380 p += (uintptr_t) pool->start;
367 381
368 goto done; 382 goto done;
369 383
370 } else { /* size < ngx_pagesize */ 384 } else { /* shift > ngx_slab_exact_shift */
371 385
372 page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift; 386 page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
373 page->next = &slots[slot]; 387 page->next = &slots[slot];
374 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG; 388 page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
375 389
384 398
385 p = 0; 399 p = 0;
386 400
387 done: 401 done:
388 402
389 ngx_shmtx_unlock(&pool->mutex);
390
391 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p); 403 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);
392 404
393 return (void *) p; 405 return (void *) p;
394 } 406 }
395 407
396 408
397 void 409 void
398 ngx_slab_free(ngx_slab_pool_t *pool, void *p) 410 ngx_slab_free(ngx_slab_pool_t *pool, void *p)
411 {
412 ngx_shmtx_lock(&pool->mutex);
413
414 ngx_slab_free_locked(pool, p);
415
416 ngx_shmtx_unlock(&pool->mutex);
417 }
418
419
420 void
421 ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
399 { 422 {
400 size_t size; 423 size_t size;
401 uintptr_t slab, *bitmap; 424 uintptr_t slab, *bitmap;
402 ngx_uint_t n, m, type, slot, shift, map; 425 ngx_uint_t n, m, type, slot, shift, map;
403 ngx_slab_page_t *slots, *page; 426 ngx_slab_page_t *slots, *page;
404 427
405 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p); 428 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
406 429
407 ngx_shmtx_lock(&pool->mutex);
408
409 if ((u_char *) p < pool->start || (u_char *) p > pool->end) { 430 if ((u_char *) p < pool->start || (u_char *) p > pool->end) {
410 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, 431 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
411 "ngx_slab_free(): outside of pool"); 432 "ngx_slab_free(): outside of pool");
412 goto fail; 433 goto fail;
413 } 434 }
582 603
583 done: 604 done:
584 605
585 ngx_slab_junk(p, size); 606 ngx_slab_junk(p, size);
586 607
587 ngx_shmtx_unlock(&pool->mutex);
588
589 return; 608 return;
590 609
591 wrong_chunk: 610 wrong_chunk:
592 611
593 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, 612 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
599 618
600 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, 619 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
601 "ngx_slab_free(): chunk is already free"); 620 "ngx_slab_free(): chunk is already free");
602 621
603 fail: 622 fail:
604
605 ngx_shmtx_unlock(&pool->mutex);
606 623
607 return; 624 return;
608 } 625 }
609 626
610 627
656 } 673 }
657 } 674 }
658 675
659 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM, 676 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, NGX_ENOMEM,
660 "ngx_slab_alloc(): failed"); 677 "ngx_slab_alloc(): failed");
678
661 return NULL; 679 return NULL;
662 } 680 }
663 681
664 682
665 static void 683 static void
672 690
673 if (pages) { 691 if (pages) {
674 ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t)); 692 ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));
675 } 693 }
676 694
677 prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK); 695 if (page->next) {
678 prev->next = page->next; 696 prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK);
679 697 prev->next = page->next;
698 page->next->prev = page->prev;
699 }
700
701 page->prev = (uintptr_t) &pool->free;
680 page->next = pool->free.next; 702 page->next = pool->free.next;
703
704 page->next->prev = (uintptr_t) page;
705
681 pool->free.next = page; 706 pool->free.next = page;
682
683 page->prev = page->next->prev;
684 page->next->prev = (uintptr_t) page;
685 } 707 }