pub trait DeviceAllocator:
Send
+ Sync
+ Debug {
// Required methods
fn allocate(
&self,
bytes: usize,
align: usize,
) -> Result<NonNull<u8>, MemoryError>;
unsafe fn deallocate(&self, ptr: NonNull<u8>, bytes: usize, align: usize);
fn device(&self) -> DeviceKey;
// Provided methods
unsafe fn deallocate_with_unmapped(
&self,
ptr: NonNull<u8>,
bytes: usize,
align: usize,
) -> u64 { ... }
unsafe fn release(
&self,
ptr: NonNull<u8>,
bytes: usize,
align: usize,
) -> AllocationReleaseOutcome { ... }
fn commits_on_demand(&self) -> bool { ... }
fn as_virtual_backing(&self) -> Option<&dyn VirtualBacking> { ... }
fn as_shared_mapping(&self) -> Option<&dyn SharedMapping> { ... }
}Expand description
Somewhere ordinary memory comes from.
An eager allocator implements only these three required methods. It does not implement degenerate commit/decommit or sharing methods.
§Safety and coherence contract
This raw-pointer boundary is trusted. Implementations must return unique,
suitably aligned live allocations and must release only their own
allocations. A capability returned by as_virtual_backing
or as_shared_mapping must operate on the same
selected mechanism and DeviceKey as this allocator, and that answer must
remain stable for the allocator’s lifetime. Transparent wrappers may
forward all three interfaces to one coherent inner mechanism.
Rust does not structurally prove that a hostile wrapper delegates its ordinary allocation, optional capabilities, and release to one inner object. Runtime identity heuristics are not a security boundary here. In-tree unsafe implementations are responsible for satisfying this contract and are tested as coherent units.
Whole-allocation terminal release always comes back through this trait,
including allocations reserved through VirtualBacking. Optional
capability traits never take ownership of terminal release.
Required Methods§
Sourcefn allocate(
&self,
bytes: usize,
align: usize,
) -> Result<NonNull<u8>, MemoryError>
fn allocate( &self, bytes: usize, align: usize, ) -> Result<NonNull<u8>, MemoryError>
Take bytes aligned to align.
Sourceunsafe fn deallocate(&self, ptr: NonNull<u8>, bytes: usize, align: usize)
unsafe fn deallocate(&self, ptr: NonNull<u8>, bytes: usize, align: usize)
Give back a whole allocation returned by this allocator or by the
VirtualBacking capability discovered from this allocator.
This is the pre-Phase-4 migration adapter. It cannot report partial
failure, so new code should implement and call
release instead; the default release forwards here
so existing implementations keep working unchanged.
§Safety
ptr must identify one live allocation from this coherent mechanism
with exactly this bytes and align, and must not be released twice.
fn device(&self) -> DeviceKey
Provided Methods§
Sourceunsafe fn deallocate_with_unmapped(
&self,
ptr: NonNull<u8>,
bytes: usize,
align: usize,
) -> u64
unsafe fn deallocate_with_unmapped( &self, ptr: NonNull<u8>, bytes: usize, align: usize, ) -> u64
Give back a whole allocation and report bytes whose global mapping reference transitioned to unmapped.
Eager allocators have no mapped attribution and inherit zero. This remains part of canonical whole-allocation release; it is intentionally not a method on either optional capability.
Like deallocate, this is a migration adapter that
cannot express partial failure. Zero is a valid answer here and never
means the release failed.
§Safety
The same requirements as deallocate.
Sourceunsafe fn release(
&self,
ptr: NonNull<u8>,
bytes: usize,
align: usize,
) -> AllocationReleaseOutcome
unsafe fn release( &self, ptr: NonNull<u8>, bytes: usize, align: usize, ) -> AllocationReleaseOutcome
Give back a whole allocation and report a structured outcome.
This is the Phase-4 canonical release entry point. It is additive: the
default implementation is an eager adapter over
deallocate_with_unmapped, so every
existing allocator keeps working unchanged and reports
AllocationReleaseOutcome::Complete.
§Honesty requirements
AllocationReleaseOutcome::Completemeans the whole allocation is gone (freed or pooled). Zero unmapped bytes is a valid complete result and must never be used to signal failure.AllocationReleaseOutcome::Failedmay be returned only when nothing was mutated. It is the one shape that implies “unchanged”.- Any partial mutation — some granules unmapped, some handles released,
an error partway through a multi-step teardown — must be
AllocationReleaseOutcome::Quarantinedcarrying the bytes actually unmapped and the residual ownership that remains.
§Safety
The same requirements as deallocate.
Sourcefn commits_on_demand(&self) -> bool
fn commits_on_demand(&self) -> bool
Whether this allocator maps physical memory lazily and charges a governor as each physical commitment is made.
This is an accounting promise, not capability discovery. An allocator
may expose VirtualBacking while returning false here when its
commit operations are not integrated with a governor. Consumers that
skip an eager full-footprint reservation rely on both halves of this
contract, so false is the safe default.
Sourcefn as_virtual_backing(&self) -> Option<&dyn VirtualBacking>
fn as_virtual_backing(&self) -> Option<&dyn VirtualBacking>
Discover lazy reserve/commit/decommit support from this selected allocator reference.
Discover shared physical mapping support independently from virtual backing support.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".