Skip to main content

DeviceAllocator

Trait DeviceAllocator 

Source
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§

Source

fn allocate( &self, bytes: usize, align: usize, ) -> Result<NonNull<u8>, MemoryError>

Take bytes aligned to align.

Source

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.

Source

fn device(&self) -> DeviceKey

Provided Methods§

Source

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.

Source

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::Complete means 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::Failed may 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::Quarantined carrying the bytes actually unmapped and the residual ownership that remains.
§Safety

The same requirements as deallocate.

Source

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.

Source

fn as_virtual_backing(&self) -> Option<&dyn VirtualBacking>

Discover lazy reserve/commit/decommit support from this selected allocator reference.

Source

fn as_shared_mapping(&self) -> Option<&dyn SharedMapping>

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".

Implementors§