Skip to main content

reserve_aligned

Function reserve_aligned 

Source
pub fn reserve_aligned(size: usize, align: usize) -> Option<Reservation>
Expand description

Reserve size bytes of anonymous virtual memory whose base is aligned to align.

  • align must be a power of two >= PAGE.
  • size must be a non-zero multiple of PAGE — the COMPILE-TIME 4 KiB constant, not the runtime page_size(). On a host where those differ (e.g. Apple Silicon macOS, 16 KiB pages), a size that is a PAGE multiple but not also a page_size() multiple is accepted here but produces a reservation whose span can never be fully decommitted: Reservation::decommit/the free decommit validate against the runtime page_size(), so decommit(0, size) on such a reservation is a debug-build panic (debug_assert!) and a silent permanent no-op in release. This is the SAME fail-closed contract try_reserve_aligned_lazy’s initial_commit parameter already enforces at the runtime granularity (task #1256/OH13-F3) — this eager constructor does not, by design, to avoid a runtime page_size() read on every call; validate against page_size() yourself first if your size is not already a multiple of the platform’s largest supported page size.

On 32-bit Unix, first tries an ordinary exact-size mmap and checks whether the kernel happened to place it at an align-aligned address (fast path; hit rate depends on the OS’s placement heuristics, not on any hint this crate passes); on a miss (wrong alignment), over-reserves size + align bytes and keeps the full mapping. On 64-bit Unix, the fast path is compiled out (target_pointer_width = "32" — see task #944, finding P-1), with ONE exception: on Linux AND Android, with the huge-pages feature on, a request for align == LINUX_HUGE_PAGE_SIZE (2 MiB) huge pages takes an exact-size MAP_HUGETLB attempt first, which when it succeeds reserves exactly size. That exception is gated on any(target_os = "linux", target_os = "android") + feature = "huge-pages", NOT on pointer width — which is both why it still fires on 64-bit and why calling it Linux-only would be wrong. When it does not apply, a 64-bit Unix reservation over-reserves size + align bytes in one mmap call. On Windows, uses one syscall (fast path for align <= 64 KiB, over-reserving nothing — base == region) or two syscalls (over-reserving size + align and keeping the full mapping). The Reservation::reservation_ptr / reservation_len fields expose the full reservation; Reservation::as_ptr / len expose the aligned usable span.

Cost on 32-bit Unix fast-path miss: the reservation holds size + align bytes of virtual address space for its lifetime (measured hit rate: 34.4% at 64 KiB align, 46.7% at 1 MiB, 56.7% at 4 MiB — commit 35d51e6, task #849; measured on WSL2/Linux, x86_64; 30-run aggregate; scope: 32-bit only — the hit rate is kernel- and ASLR-dependent and is not expected to transfer to other Unix platforms). On 64-bit Unix these numbers do not apply: the fast path never runs, so every reservation pays the “miss” cost of size + align bytes held for the reservation’s lifetime, unconditionally.

Returns None on a contract violation or if the OS refuses the reservation (OOM) — never panics, so it is safe to call from inside a GlobalAlloc implementation. For the failure cause use try_reserve_aligned.