Claim an aligned address range for huge pages
| 1242 | |
| 1243 | // Claim an aligned address range for huge pages |
| 1244 | static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { |
| 1245 | if (total_size != NULL) *total_size = 0; |
| 1246 | const size_t size = pages * MI_HUGE_OS_PAGE_SIZE; |
| 1247 | |
| 1248 | uintptr_t start = 0; |
| 1249 | uintptr_t end = 0; |
| 1250 | uintptr_t huge_start = mi_atomic_load_relaxed(&mi_huge_start); |
| 1251 | do { |
| 1252 | start = huge_start; |
| 1253 | if (start == 0) { |
| 1254 | // Initialize the start address after the 32TiB area |
| 1255 | start = ((uintptr_t)32 << 40); // 32TiB virtual start address |
| 1256 | #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of huge pages unless in debug mode |
| 1257 | uintptr_t r = _mi_heap_random_next(mi_get_default_heap()); |
| 1258 | start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF)); // (randomly 12bits)*1GiB == between 0 to 4TiB |
| 1259 | #endif |
| 1260 | } |
| 1261 | end = start + size; |
| 1262 | mi_assert_internal(end % MI_SEGMENT_SIZE == 0); |
| 1263 | } while (!mi_atomic_cas_strong_acq_rel(&mi_huge_start, &huge_start, end)); |
| 1264 | |
| 1265 | if (total_size != NULL) *total_size = size; |
| 1266 | return (uint8_t*)start; |
| 1267 | } |
| 1268 | #else |
| 1269 | static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { |
| 1270 | MI_UNUSED(pages); |
no test coverage detected