Skip to main content

RegionedAllocator

Struct RegionedAllocator 

Source
pub struct RegionedAllocator<const REGIONS: usize, A, S = NoCpuId> { /* private fields */ }
Expand description

A wrapper that routes over REGIONS disjoint physical spans, one unmodified inner allocator A per span.

All regions are expected to share the same backend configuration — base frame, order count, and max_page.

Allocation starts on the calling CPU’s home region (CpuId::current_cpu modulo REGIONS, or region 0 under the default NoCpuId) and work-steals round-robin through the other regions on local OutOfMemory.

Deallocation and add_usable route by physical address to the owning region. An address owned by no region is dropped (debug builds panic).

Implementations§

Source§

impl<const REGIONS: usize, A, S> RegionedAllocator<REGIONS, A, S>

Source

pub const fn new(base_frame: PageSize, regions: [A; REGIONS]) -> Self

Create a new, uninitialised regioned allocator from REGIONS pre-built inner allocators.

base_frame must match the base frame size of every inner allocator.

Source

pub unsafe fn try_init_at( &self, idx: usize, phys_base: usize, span_len: usize, usable: &[PhysRange], ) -> Result<(), InitError>
where A: RegionInit,

Fallible initialisation of region idx over the disjoint physical span [phys_base, phys_base + span_len), freeing only usable. Delegates to the backend’s RegionInit::try_init and records the span for address routing.

Call at most once successfully per region index, single-threaded and before publishing the allocator to concurrent users. On Err the region is left untouched - a corrected retry is permitted.

§Errors
§Panics

If idx >= REGIONS (a structural bug, like any out-of-bounds index).

§Safety

The (phys_base, span_len, usable) arguments must satisfy the backend’s RegionInit::try_init safety contract, including the single-threaded pre-publication requirement. The spans of distinct regions must be disjoint, and no two try_init_at calls may race with each other.

Source

pub unsafe fn init_at( &self, idx: usize, phys_base: usize, span_len: usize, usable: &[PhysRange], )
where A: RegionInit,

As try_init_at but panic on any InitError.

Call once per region index, single-threaded, before publishing the allocator to concurrent users. (Same as try_init_at).

§Safety

idx < REGIONS. The (phys_base, span_len, usable) arguments must satisfy the backend’s RegionInit::try_init contract, including the single-threaded pre-publication requirement. The spans of distinct regions must be disjoint, and no two init_at/try_init_at calls may race with each other.

§Panics

If idx >= REGIONS, or if initialisation returns an InitError.

Source

pub unsafe fn add_usable(&self, base: usize, len: usize)
where A: RegionInit,

Transition a reserved in-span range to free, routed to the owning region. The repeatable post-init counterpart of RegionInit::add_usable

§Safety

[base, base + len) must lie within a single initialised region’s span, be currently reserved (not already free), exclusively owned, and not aliased while registered.

Source

pub fn alloc_in_region( &self, idx: usize, ps: PageSize, count: NonZeroUsize, ) -> Result<usize, AllocError>

Allocate strictly within region idx

§Panics

If idx >= REGIONS.

Source

pub fn alloc_in_chain( &self, chain: &[usize], ps: PageSize, count: NonZeroUsize, ) -> Result<usize, AllocError>

Allocate from the first region in chain that can satisfy the request, trying them in the given order

§Panics

If any index in chain is >= REGIONS.

Trait Implementations§

Source§

impl<const REGIONS: usize, A, S> PhysicalAllocator for RegionedAllocator<REGIONS, A, S>
where A: PhysicalAllocator, S: CpuId,

Source§

fn allocate_physical( &self, ps: PageSize, count: NonZeroUsize, ) -> Result<usize, AllocError>

Allocate count contiguous frames of size ps. Read more
Source§

unsafe fn deallocate_physical( &self, ps: PageSize, count: NonZeroUsize, phys: usize, )

Return count contiguous frames of size ps starting at phys. Read more

Auto Trait Implementations§

§

impl<const REGIONS: usize, A, S = NoCpuId> !Freeze for RegionedAllocator<REGIONS, A, S>

§

impl<const REGIONS: usize, A, S> RefUnwindSafe for RegionedAllocator<REGIONS, A, S>
where A: RefUnwindSafe,

§

impl<const REGIONS: usize, A, S> Send for RegionedAllocator<REGIONS, A, S>
where A: Send,

§

impl<const REGIONS: usize, A, S> Sync for RegionedAllocator<REGIONS, A, S>
where A: Sync,

§

impl<const REGIONS: usize, A, S> Unpin for RegionedAllocator<REGIONS, A, S>
where A: Unpin,

§

impl<const REGIONS: usize, A, S> UnsafeUnpin for RegionedAllocator<REGIONS, A, S>
where A: UnsafeUnpin,

§

impl<const REGIONS: usize, A, S> UnwindSafe for RegionedAllocator<REGIONS, A, S>
where A: UnwindSafe,

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.