Struct vmem::Arena

source ·
pub struct Arena<'label, 'src, A: Allocator, L: Lock> { /* private fields */ }
Expand description

A vmem arena.

This arena can be used for allocation of any resource that can be represented by a base and a length. However, it is quite inefficient in its memory usage for small allocations, so it is recommended to allocate larger blocks and then suballocate from those, unless memory usage is not a concern.

§Usage

In order to create an arena, two things are needed:

  • A locking mechanism. You have many choices. Whatever you decide to use, it must implement lock::Lock. The trait is implemented by [spin::Mutex<()>] by default, but that does not mean that you should use [spin]’s mutex. Spinlocks are rarely the right choice for a lock.
  • An allocator. This is the type that will be used to allocate the boundary tags used within the allocator. It must implement the alloc::Allocator trait. With the nightly feature, the trait is implemented for all types that implement core::alloc::Allocator.

Once you have these things, you can move on to Arena::create:

let arena = Arena::<_, Lock>::create("test", 8, None, Allocator).unwrap();
§Why unwrap?

The create function only returns an error if the specified quantum value is not a power of two. Since we know that 8 is a power of two, we can unwrap the value without worrying about any panics.

§Filling the arena

Without a source, arenas are empty by default. In order to allocate from them, you must first add a span via Arena::add_span. This function takes a base and a length, and marks it as available for allocation.

§Importing from a source

A source can be another arena, or any other type that implements Source. In order to add a source to an arena, you must pass it to the parameter source during creation. Once a source is specified, allocations will be redirected there (unless the arena has its own free spans available).

Implementations§

source§

impl<'label, 'src, A: Allocator, L: Lock> Arena<'label, 'src, A, L>

source

pub fn create( label: &'label str, quantum: usize, source: Option<&'src dyn Source>, allocator: A ) -> Result<Self>

Create a new empty arena.

§Parameters
  • label - a label for the arena. This is used for debugging purposes.
  • quantum - the quantum of the arena. It is the smallest transactional unit in the arena (meaning that any allocations within the arena will be rounded up to and aligned to a multiple of it), and must be a power of two.
  • source - an optional source for allocations. If specified, any calls to alloc or xalloc that fail will be forwarded to the source. If not specified, allocations will fail directly if the arena is empty.
  • allocator - the allocator to use for allocating boundary tags.
§Returns

If the quantum is not a power of two, Error::InvalidQuantum will be returned. Otherwise, the function will return an arena

source

pub fn add_span(&self, base: usize, len: usize) -> Result<()>

Add a span to the arena. The span will be used for future allocations.

§Parameters
  • base - the base of the span. This is the address of the first byte or index of the span. Do note that it is not a multiple of quantum, but the actual value.
  • len - the length of the span. This is the number of bytes or indices in the span. Do note that it is not a multiple of quantum, but the actual value.
§Returns

If the span could not be added, one of these errors will be returned:

source

pub fn import(&self, layout: Layout) -> Result<()>

Borrow a span from the source, and add it to the arena.

§Parameters
  • layout - the layout of the span to borrow. See Layout for more details.
§Returns

If a span could not be borrowed, this function will forward the error given by the source. The function could also return one of these errors:

source

pub fn alloc(&self, size: usize, policy: AllocPolicy) -> Result<usize>

Allocates a block based on a size and an allocation policy.

§Parameters
  • size - the size of the block to allocate. This is the number of bytes or indices in the block. Do note that it is not a multiple of quantum, but the actual value.
  • policy - the allocation policy to use. See AllocPolicy for more details.
§Returns

If a block could not be allocated, one of the following errors will be returned:

If a source is specified, this function will forward any errors given by it.

source

pub fn xalloc(&self, layout: Layout, policy: AllocPolicy) -> Result<usize>

Allocates a block based on a layout and an allocation policy. See Layout for more details on what features are supported.

§Parameters
  • layout - the layout of the block to allocate.
  • policy - the allocation policy to use. See AllocPolicy for more details.
§Returns

If a block could not be allocated, one of the following errors will be returned:

If a source is specified, this function will forward any errors given by it.

§Panics

This function will panic if you attempt to call it with AllocPolicy::NextFit. This policy is purposefully unsupported.

source

pub fn free(&self, base: usize) -> Result<()>

Free a block of memory.

§Parameters
  • base - the base of the block to free. This is the address of the first byte or index of the block. Do note that it is not a multiple of quantum, but the actual value.
§Returns

If the block could not be freed, one of the following errors will be returned:

source

pub fn total_space(&self) -> usize

Get the total space contained in this arena.

Note that this iterates the entire list, and as such is not incredibly performant. This may change in the future.

§Returns

The total space contained in this arena, in terms of bytes/indices. This includes both allocated and free space, including borrowed space.

source

pub fn allocated_space(&self) -> usize

Get the allocated space contained in this arena.

Note that this iterates the entire list, and as such is not incredibly performant. This may change in the future.

§Returns

The allocated space contained in this arena, in terms of bytes/indices. This includes both borrowed and non-borrowed allocations.

source

pub fn free_space(&self) -> usize

Get the free space contained in this arena.

Note that this iterates the entire list, and as such is not incredibly performant. This is subject to change in the future.

§Returns

The free space contained in this arena, in terms of bytes/indices. This includes both borrowed and non-borrowed allocations.

source

pub fn borrowed_space(&self) -> usize

Get the borrowed space contained in this arena.

Note that this iterates the entire list, and as such is not incredibly performant. This is subject to change in the future.

§Returns

The borrowed space contained in this arena, in terms of bytes/indices. This includes both free and allocated borrowed space.

source

pub fn label(&self) -> &'label str

Get the label for this arena.

Trait Implementations§

source§

impl<'label, 'src, A: Allocator, L: Lock> Debug for Arena<'label, 'src, A, L>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'label, 'src, A: Allocator, L: Lock> Drop for Arena<'label, 'src, A, L>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'label, 'src, A: Allocator + Sync, L: Lock + Sync> Source for Arena<'label, 'src, A, L>

source§

fn import(&self, layout: Layout) -> Result<usize>

Import a block that satisfies Layout from this source, returning its base. Read more
source§

unsafe fn release(&self, base: usize, _size: usize) -> Result<()>

Release a block of memory that was previously imported from this source. Read more
source§

impl<'label, 'src, A: Allocator + Send, L: Lock + Send> Send for Arena<'label, 'src, A, L>

source§

impl<'label, 'src, A: Allocator + Sync, L: Lock + Sync> Sync for Arena<'label, 'src, A, L>

Auto Trait Implementations§

§

impl<'label, 'src, A, L> !RefUnwindSafe for Arena<'label, 'src, A, L>

§

impl<'label, 'src, A, L> Unpin for Arena<'label, 'src, A, L>
where A: Unpin, L: Unpin,

§

impl<'label, 'src, A, L> !UnwindSafe for Arena<'label, 'src, A, L>

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>,

§

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>,

§

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.