Skip to main content

LazyReservation

Struct LazyReservation 

Source
pub struct LazyReservation { /* private fields */ }
Available on crate feature lazy-commit only.
Expand description

A Reservation that also tracks how much of itself is committed.

The tracked counterpart to the raw commit primitives. A plain Reservation describes GEOMETRY — where the span is, how long, how aligned — but virtual memory also has STATE per page (reserved / committed), and a bare Reservation holds none of it. Every caller of the lazy path therefore had to invent the same bookkeeping. This type holds it instead.

§What is tracked, and what deliberately is not

Exactly one number: a watermark. [0, committed_len()) is committed; [committed_len(), len()) is not. Arbitrary committed/uncommitted HOLES are not representable, and that is a drawn boundary rather than an oversight — the dominant lazy-reservation shape is grow-only, a watermark covers it in one usize, and anything more general is a per-page bitmap, which is an allocator’s job and not this crate’s. A caller that genuinely needs holes already has its own metadata plane and should take into_reservation and drive the raw primitives.

§Why the mutating methods take &mut self

Not bookkeeping hygiene — this is the crate finally stating a requirement it always had. A watermark is inherently racy: two threads committing concurrently must serialise, and under the raw primitives nothing ever said so. &mut self makes the compiler ask for the synchronisation that was always necessary, instead of leaving it to be discovered in production. (After task #1113, the raw Reservation also follows this rule.)

§The watermark is a guarantee, not a prohibition

committed_len() is what this crate GUARANTEES writable. Where decommit is advisory rather than reclaiming (see Reservation::decommit_reclaims_and_zeroes) memory past the watermark may still be resident and writable after shrink_committed. Relying on that is exactly the non-portable assumption this type exists to prevent — treat the watermark as the contract.

§It can still be bypassed, and that is honest

as_ptr hands out the raw pointer; it must, or you could not write to the memory. Passing that pointer to the raw commit primitives changes OS state behind the watermark’s back and the watermark goes stale. No API over raw memory can prevent that. What changes is the DEFAULT: the tracked path is what you get without asking, and the bypass now requires deliberately reaching for a differently-named function.

After task #1104 there are exactly two doors out, and both are deliberate: the raw pointer above — every USE of which is already unsafe — and into_reservation, which consumes this handle, so the watermark cannot outlive its own tracking. A borrowed &Reservation was removed at task #1104; after task #1113 the OS-state mutators on Reservation take &mut self, so even a leaked &Reservation can no longer mutate OS state — the seal is structural. The read-only queries callers actually need — len, as_ptr, align — are proxied directly on this type; anything else lives behind into_reservation on purpose.

A LazyReservation is never huge-page backed — the lazy constructors always request ordinary pages — so there is no is_huge() here. It would be a constant false dressed up as a question.

Implementations§

Source§

impl LazyReservation

Source

pub const fn committed_len(&self) -> usize

Bytes from the base that are committed and writable.

Where lazy_commit_is_honored is false this equals len from the moment of creation.

Source

pub fn ensure_committed(&mut self, len: usize) -> Result<(), VmemError>

Ensure at least len bytes from the base are committed.

Idempotent and monotone — the point of the whole type. Call it before every write without remembering what you already committed: a call asking for no more than the current watermark issues no syscall and returns Ok(()).

len need NOT be page-aligned; it is rounded UP to the runtime page size internally, so asking for one byte past the watermark commits the page containing it.

§Errors

VmemError::invalid_argument if len > len(); otherwise the OS cause when the commit genuinely fails (commit-charge exhaustion / OOM).

On failure the watermark is left unchanged, so the handle still describes exactly what is committed and a retry is safe.

Source

pub fn shrink_committed(&mut self, len: usize)

Lower the watermark to len, asking the OS to release [new watermark, old watermark).

len is rounded UP to the runtime page size, so a page containing bytes you asked to KEEP is never released. Asking for at least the current watermark is a no-op.

What the OS does with the released range is platform-dependent — see Reservation::decommit’s platform matrix. The watermark drops regardless, because it is this crate’s guarantee and not a claim about residency.

Source

pub fn into_reservation(self) -> Reservation

Give up tracking and take the plain Reservation.

The explicit door out, for a caller keeping its own commit state. The motivating case is an allocator whose watermark must live in its own metadata, reachable from a bare pointer on a hot path where no handle is in scope. After this call the crate tracks nothing and the raw primitives are yours to drive.

Source

pub fn as_ptr(&self) -> *mut u8

Base pointer of the usable span. See Reservation::as_ptr.

Source

pub const fn len(&self) -> usize

Usable length of the span — committed and uncommitted together.

Source

pub const fn is_empty(&self) -> bool

Whether the usable span is empty. Always false for a reservation this crate produced (a zero-size request is rejected); present because clippy asks for it alongside len.

Source

pub const fn align(&self) -> usize

Alignment the span was reserved with. See Reservation::align.

Trait Implementations§

Source§

impl Debug for LazyReservation

Hand-written for the same reason Reservation’s is: the type’s whole point is one piece of diagnostically decisive state — the watermark — and it must be visible in a panic message. Field selection follows the same principle as Reservation’s impl: print only what is already publicly observable (committed_len(), and the inner reservation, whose own Debug prints exactly its public observables). The inner reservation is rendered, not borrowed out — formatting goes through Debug, so no &Reservation escapes and the H1 sealing (task #1104) is unaffected.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.