Skip to main content

Arena

Struct Arena 

Source
pub struct Arena { /* private fields */ }
Expand description

One leased buffer from a ArenaPool. Send + Sync.

Allocations are bump-pointer on an atomic cursor: each call to Arena::alloc CAS-advances the cursor and returns a fresh aligned slice carved out of the buffer at the old position. There is no per-allocation header and no individual free — the entire arena is reset (returned to the pool) only when the Arena is dropped.

Concurrent calls to Arena::alloc on the same &Arena are supported and produce disjoint slices (the CAS loser retries against the new cursor). See the module docs for the full concurrency contract.

Implementations§

Source§

impl Arena

Source

pub fn capacity(&self) -> usize

Capacity of this arena in bytes.

Source

pub fn used(&self) -> usize

Bytes consumed by allocations so far.

Source

pub fn alloc_count(&self) -> u32

Number of allocations performed so far.

Source

pub fn alloc_count_exceeded(&self) -> bool

true once the per-arena allocation-count cap has been reached. Decoders that produce many small allocations should poll this and bail with Error::ResourceExhausted when it flips, instead of waiting for the next Arena::alloc call to fail.

Source

pub fn alloc<T>(&self, count: usize) -> Result<&mut [T]>
where T: Zeroable,

Allocate count Ts out of this arena. Returns a borrowed &mut [T] (lifetime bounded by the borrow of self).

The returned slice points at zero-filled bytes (the pool zero-fills on initial allocation and again whenever a buffer is returned). The Zeroable bound on T guarantees that an all-zero bit pattern is a valid value for T, so reading the slice without first writing it is sound. The intended pattern is still “decoder fills the slice, then reads back what it wrote” — but unwritten bytes will read back as T::zeroed() rather than as UB.

Returns Error::ResourceExhausted if either the per-arena byte cap or the per-arena allocation-count cap would be exceeded.

§Type bounds
  • T: bytemuck::Zeroable — pool buffers are zero-filled, so handing back &mut [T] over those bytes is only sound when the all-zero bit pattern is valid for T. This rules out NonZeroU8/NonZeroU16/…/references/function pointers/ niche-optimised enums.
  • align_of::<T>() <= MAX_ALIGN — checked at compile time via a const assertion. The pool buffer’s base pointer is aligned to [MAX_ALIGN] (= 64 bytes); per-T alignment is then a relative-offset adjustment of the bump cursor.
  • The arena does not run destructors on allocated values, so T should not have meaningful Drop glue.

Concurrency: the bump cursor is advanced via a CAS loop, so concurrent alloc calls on the same &Arena produce disjoint slices. The CAS loser retries against the new cursor; in the uncontended case the cost is a single relaxed load plus one successful CAS. Crucially, no alloc call re-borrows the whole buffer (the typed pointer is derived from the cached raw base pointer), so concurrent allocators cannot invalidate each other’s previously-returned slices under stacked borrows.

Source

pub fn reset(&mut self)

Reset the arena to empty without releasing its buffer to the pool. Useful for a decoder that wants to reuse the same arena across several intermediate stages of the same frame. Callers must ensure no slice previously returned from Arena::alloc is still in use — Rust’s borrow checker enforces this, since reset takes &mut self.

Trait Implementations§

Source§

impl Drop for Arena

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Arena

Source§

impl Sync for Arena

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.