| 1519 | ----------------------------------------------------------- */ |
| 1520 | |
| 1521 | static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) |
| 1522 | { |
| 1523 | mi_page_t* page = NULL; |
| 1524 | mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,os_tld,&page); |
| 1525 | if (segment == NULL || page==NULL) return NULL; |
| 1526 | mi_assert_internal(segment->used==1); |
| 1527 | mi_assert_internal(mi_page_block_size(page) >= size); |
| 1528 | #if MI_HUGE_PAGE_ABANDON |
| 1529 | segment->thread_id = 0; // huge segments are immediately abandoned |
| 1530 | #endif |
| 1531 | |
| 1532 | // for huge pages we initialize the xblock_size as we may |
| 1533 | // overallocate to accommodate large alignments. |
| 1534 | size_t psize; |
| 1535 | uint8_t* start = _mi_segment_page_start(segment, page, &psize); |
| 1536 | page->xblock_size = (psize > MI_HUGE_BLOCK_SIZE ? MI_HUGE_BLOCK_SIZE : (uint32_t)psize); |
| 1537 | |
| 1538 | // decommit the part of the prefix of a page that will not be used; this can be quite large (close to MI_SEGMENT_SIZE) |
| 1539 | if (page_alignment > 0 && segment->allow_decommit) { |
| 1540 | uint8_t* aligned_p = (uint8_t*)_mi_align_up((uintptr_t)start, page_alignment); |
| 1541 | mi_assert_internal(_mi_is_aligned(aligned_p, page_alignment)); |
| 1542 | mi_assert_internal(psize - (aligned_p - start) >= size); |
| 1543 | uint8_t* decommit_start = start + sizeof(mi_block_t); // for the free list |
| 1544 | ptrdiff_t decommit_size = aligned_p - decommit_start; |
| 1545 | _mi_os_decommit(decommit_start, decommit_size, &_mi_stats_main); // note: cannot use segment_decommit on huge segments |
| 1546 | } |
| 1547 | |
| 1548 | return page; |
| 1549 | } |
| 1550 | |
| 1551 | #if MI_HUGE_PAGE_ABANDON |
| 1552 | // free huge block from another thread |
no test coverage detected