pub unsafe fn try_decommit(
base: *mut u8,
start: usize,
end: usize,
) -> Result<DecommitOutcome, VmemError>Expand description
Fallible decommit: the same operation, with a channel for the one thing
decommit cannot report — and, since task #1180 (PUB-R2 phase 2), a
channel for the OS’s own accept/refuse answer too, not just argument
validity.
Of this crate’s state-changing primitives, decommit/decommit_lazy were
the only pair with no fallible twin — and also the only ones that do nothing
at all on a contract violation. The worst two properties met in one place:
silent AND unreportable. This closes the first half.
§Errors
VmemError::invalid_argument if start > end, or either endpoint is not
a multiple of the runtime page_size(). An empty page-aligned range
(start == end) is a well-formed no-op and returns Ok(DecommitOutcome::Skipped).
VmemError::os_refusal_unknown_code if the one-time OS page-size query
itself failed — the caller’s arguments are not at fault; see
page_size()’s “If the one-time OS query fails” paragraph.
Note what is deliberately NOT reported as an Err (the outer Result
keeps reporting only caller-contract validity, exactly as before this
task): the OS refusing or ignoring the request is Ok(DecommitOutcome::Refused(_)),
not Err. decommit is best-effort by nature — on Darwin and the BSDs
MADV_DONTNEED is advisory, and on a huge-page reservation eligibility
depends on the platform, the requested range, and (on Linux/Android) the
running kernel — see decommit’s “Huge-page granularity” section above
for the exact split. Promoting an OS refusal to Err would conflate “your
arguments were rejected” with “the platform declined to honor a
well-formed request”, which is exactly the ambiguity
DecommitOutcome exists to separate. Use
Reservation::decommit_reclaims_and_zeroes to learn what the platform
actually does; DecommitOutcome::Advised/DecommitOutcome::Refused tell
you what THIS call did, not what it accomplished (see that type’s own doc).
This free function always either short-circuits on an empty range
(Ok(DecommitOutcome::Skipped)) or forwards to the real backend — it has
no Reservation::is_huge to consult, so unlike
Reservation::try_decommit it can never produce Skipped for a
non-empty range; every non-empty well-formed range here becomes either
Advised or Refused.
§Safety
Identical to decommit: base must be the usable base of a live
reservation owned by the caller, and [base+start, base+end) must lie
within its usable span.