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>
impl<const REGIONS: usize, A, S> RegionedAllocator<REGIONS, A, S>
Sourcepub const fn new(base_frame: PageSize, regions: [A; REGIONS]) -> Self
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.
Sourcepub unsafe fn try_init_at(
&self,
idx: usize,
phys_base: usize,
span_len: usize,
usable: &[PhysRange],
) -> Result<(), InitError>where
A: RegionInit,
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
InitError::Misalignedifphys_baseis not base-frame aligned;InitError::InvalidSpanifspan_lenis zero, not a base-frame multiple, or overflows the address space;InitError::AlreadyInitializedif regionidxwas already initialised;InitError::OverlapsRegionif the span overlaps an initialised region;- any error returned by the backend’s
RegionInit::try_init.
§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.
Sourcepub unsafe fn init_at(
&self,
idx: usize,
phys_base: usize,
span_len: usize,
usable: &[PhysRange],
)where
A: RegionInit,
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.
Sourcepub unsafe fn add_usable(&self, base: usize, len: usize)where
A: RegionInit,
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.
Sourcepub fn alloc_in_region(
&self,
idx: usize,
ps: PageSize,
count: NonZeroUsize,
) -> Result<usize, AllocError>where
A: PhysicalAllocator,
pub fn alloc_in_region(
&self,
idx: usize,
ps: PageSize,
count: NonZeroUsize,
) -> Result<usize, AllocError>where
A: PhysicalAllocator,
Sourcepub fn alloc_in_chain(
&self,
chain: &[usize],
ps: PageSize,
count: NonZeroUsize,
) -> Result<usize, AllocError>where
A: PhysicalAllocator,
pub fn alloc_in_chain(
&self,
chain: &[usize],
ps: PageSize,
count: NonZeroUsize,
) -> Result<usize, AllocError>where
A: PhysicalAllocator,
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.