Mercurial > hg > nginx-vendor-1-0
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 } |