* Find an extent with size [min_size, max_size) to satisfy the alignment * requirement. For each size, try only the first extent in the heap. */
| 403 | * requirement. For each size, try only the first extent in the heap. |
| 404 | */ |
| 405 | static extent_t * |
| 406 | extents_fit_alignment(extents_t *extents, size_t min_size, size_t max_size, |
| 407 | size_t alignment) { |
| 408 | pszind_t pind = sz_psz2ind(extent_size_quantize_ceil(min_size)); |
| 409 | pszind_t pind_max = sz_psz2ind(extent_size_quantize_ceil(max_size)); |
| 410 | |
| 411 | for (pszind_t i = (pszind_t)bitmap_ffu(extents->bitmap, |
| 412 | &extents_bitmap_info, (size_t)pind); i < pind_max; i = |
| 413 | (pszind_t)bitmap_ffu(extents->bitmap, &extents_bitmap_info, |
| 414 | (size_t)i+1)) { |
| 415 | assert(i < SC_NPSIZES); |
| 416 | assert(!extent_heap_empty(&extents->heaps[i])); |
| 417 | extent_t *extent = extent_heap_first(&extents->heaps[i]); |
| 418 | uintptr_t base = (uintptr_t)extent_base_get(extent); |
| 419 | size_t candidate_size = extent_size_get(extent); |
| 420 | assert(candidate_size >= min_size); |
| 421 | |
| 422 | uintptr_t next_align = ALIGNMENT_CEILING((uintptr_t)base, |
| 423 | PAGE_CEILING(alignment)); |
| 424 | if (base > next_align || base + candidate_size <= next_align) { |
| 425 | /* Overflow or not crossing the next alignment. */ |
| 426 | continue; |
| 427 | } |
| 428 | |
| 429 | size_t leadsize = next_align - base; |
| 430 | if (candidate_size - leadsize >= min_size) { |
| 431 | return extent; |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | return NULL; |
| 436 | } |
| 437 | |
| 438 | /* |
| 439 | * Do first-fit extent selection, i.e. select the oldest/lowest extent that is |
no test coverage detected