| 546 | #else |
| 547 | #define MI_OS_USE_MMAP |
| 548 | static void* mi_unix_mmapx(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) { |
| 549 | MI_UNUSED(try_alignment); |
| 550 | #if defined(MAP_ALIGNED) // BSD |
| 551 | if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { |
| 552 | size_t n = mi_bsr(try_alignment); |
| 553 | if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB |
| 554 | flags |= MAP_ALIGNED(n); |
| 555 | void* p = mmap(addr, size, protect_flags, flags | MAP_ALIGNED(n), fd, 0); |
| 556 | if (p!=MAP_FAILED) return p; |
| 557 | // fall back to regular mmap |
| 558 | } |
| 559 | } |
| 560 | #elif defined(MAP_ALIGN) // Solaris |
| 561 | if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0) { |
| 562 | void* p = mmap((void*)try_alignment, size, protect_flags, flags | MAP_ALIGN, fd, 0); // addr parameter is the required alignment |
| 563 | if (p!=MAP_FAILED) return p; |
| 564 | // fall back to regular mmap |
| 565 | } |
| 566 | #endif |
| 567 | #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED) |
| 568 | // on 64-bit systems, use the virtual address area after 2TiB for 4MiB aligned allocations |
| 569 | if (addr == NULL) { |
| 570 | void* hint = mi_os_get_aligned_hint(try_alignment, size); |
| 571 | if (hint != NULL) { |
| 572 | void* p = mmap(hint, size, protect_flags, flags, fd, 0); |
| 573 | if (p!=MAP_FAILED) return p; |
| 574 | // fall back to regular mmap |
| 575 | } |
| 576 | } |
| 577 | #endif |
| 578 | // regular mmap |
| 579 | void* p = mmap(addr, size, protect_flags, flags, fd, 0); |
| 580 | if (p!=MAP_FAILED) return p; |
| 581 | // failed to allocate |
| 582 | return NULL; |
| 583 | } |
| 584 | |
| 585 | static int mi_unix_mmap_fd(void) { |
| 586 | #if defined(VM_MAKE_TAG) |
no test coverage detected