pub fn page_size() -> usizeExpand description
Return the OS page size in bytes, querying the OS once and caching the result.
Uses sysconf(_SC_PAGESIZE) on Unix and GetSystemInfo on Windows; under
miri it returns PAGE (4 KiB) by design (there is no real OS page). The
value is cached in a process-wide atomic after the first call, so repeated
calls are a single relaxed load. The returned value is always a power of
two and at least PAGE.
Correctness: on Apple Silicon macOS the page size is 16 KiB, and on
some Linux configurations 64 KiB. Use this value (not PAGE) to round
decommit offsets: decommit/decommit_lazy validate BOTH endpoints
against page_size() before reaching the OS, and a misaligned endpoint is
a crate-level fail-closed skip (the call returns without any effect).
That crate-level validation is the load-bearing guard — do not rely on the
OS to reject a misaligned range for you. The kernels’ own behavior is
asymmetric and platform-divergent: Linux madvise(2) rejects the call
only when the ADDRESS is misaligned, and rounds a misaligned LENGTH up
to the real page (touching memory past the requested range); Windows
VirtualFree(MEM_DECOMMIT) rejects nothing and widens the range in BOTH
directions (it decommits every page containing any byte of the range).
If the one-time OS query fails (sysconf returning an error, or a
nonsensical answer — not observed on any supported platform: on
Linux/macOS/Windows the page size comes from process-startup data that
cannot fail to exist), this function still returns MIN_PAGE
(= PAGE, 4 KiB) so it stays infallible — but the crate records the
failure and every page-granular STATE operation fails closed for the
process lifetime: decommit/decommit_lazy become no-ops,
recommit/commit_range return false, the try_* forms and the lazy
reservation constructor report an OS-side no-code error (see
VmemError::os_refusal_unknown_code),
and try_page_size returns Err. Reserving,
using, and releasing memory are unaffected — they never depend on the
runtime page size. Rationale: with the real page size unknown, a
decommit granularity guess could make the OS round a length up across
live data; refusing to decommit loses nothing but an optimization,
while guessing risks silent data loss.
One bookkeeping value keeps moving even in the degraded state (task
#1156, finding F15):
LazyReservation::shrink_committed (feature lazy-commit; not an
intra-doc link here — page_size is compiled unconditionally and
LazyReservation is not, so a real link would break whenever
lazy-commit is off, e.g. under plain --no-default-features) lowers
its own watermark unconditionally, even though the decommit call it
issues underneath is the no-op described
above. The watermark is rounded UP using the conservative PAGE value
this degraded state substitutes for the unknown real page size, so the
dropped range can be smaller than a true page on a host with a larger
real page — but shrink_committed documents the watermark as this
crate’s own bookkeeping guarantee, “not a claim about residency”, so a
lowered watermark under poison is consistent with that contract, not a
violation of it: no committed byte the caller is entitled to is released
(the underlying decommit did nothing), only the handle’s own record of
what it considers committed moves. No other primitive’s return value
(bool, Result) is affected by this — shrink_committed is the one
entry point in this enumeration with no fallible/boolean signature to
report the degraded state through, because it never had one even outside
the degraded state.