Map new pages to virtual memory
| 1525 | |
| 1526 | //! Map new pages to virtual memory |
| 1527 | static void* |
| 1528 | _memory_map(size_t page_count) { |
| 1529 | size_t total_size = page_count * PAGE_SIZE; |
| 1530 | void* pages_ptr = 0; |
| 1531 | |
| 1532 | #if ENABLE_STATISTICS |
| 1533 | atomic_add32(&_mapped_pages, (int32_t)page_count); |
| 1534 | atomic_add32(&_mapped_total, (int32_t)page_count); |
| 1535 | #endif |
| 1536 | |
| 1537 | #ifdef PLATFORM_WINDOWS |
| 1538 | pages_ptr = VirtualAlloc(0, total_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
| 1539 | #else |
| 1540 | //mmap lacks a way to set 64KiB address granularity, implement it locally |
| 1541 | intptr_t incr = (intptr_t)total_size / (intptr_t)SPAN_ADDRESS_GRANULARITY; |
| 1542 | if (total_size % SPAN_ADDRESS_GRANULARITY) |
| 1543 | ++incr; |
| 1544 | do { |
| 1545 | void* base_addr = (void*)(uintptr_t)atomic_exchange_and_add64(&_memory_addr, |
| 1546 | (incr * (intptr_t)SPAN_ADDRESS_GRANULARITY)); |
| 1547 | pages_ptr = mmap(base_addr, total_size, PROT_READ | PROT_WRITE, |
| 1548 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED, -1, 0); |
| 1549 | if (pages_ptr != MAP_FAILED) { |
| 1550 | if (pages_ptr != base_addr) { |
| 1551 | void* new_base = (void*)((uintptr_t)pages_ptr & SPAN_MASK); |
| 1552 | atomic_store64(&_memory_addr, (int64_t)((uintptr_t)new_base) + |
| 1553 | ((incr + 1) * (intptr_t)SPAN_ADDRESS_GRANULARITY)); |
| 1554 | atomic_thread_fence_release(); |
| 1555 | } |
| 1556 | if (!((uintptr_t)pages_ptr & ~SPAN_MASK)) |
| 1557 | break; |
| 1558 | munmap(pages_ptr, total_size); |
| 1559 | } |
| 1560 | } |
| 1561 | while (1); |
| 1562 | #endif |
| 1563 | |
| 1564 | return pages_ptr; |
| 1565 | } |
| 1566 | |
| 1567 | //! Unmap pages from virtual memory |
| 1568 | static void |
no test coverage detected