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 thenightly
feature, the trait is implemented for all types that implementcore::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>
impl<'label, 'src, A: Allocator, L: Lock> Arena<'label, 'src, A, L>
sourcepub fn create(
label: &'label str,
quantum: usize,
source: Option<&'src dyn Source>,
allocator: A
) -> Result<Self>
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 toalloc
orxalloc
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
sourcepub fn add_span(&self, base: usize, len: usize) -> Result<()>
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:
Error::AllocatorError
- the allocator could not allocate a boundary tag to support this span.Error::AllocZeroSize
- the span has no size.Error::UnalignedSpan
- the span is not aligned toquantum
Error::WrappingSpan
- the span could not be added because it would overflow.
sourcepub fn import(&self, layout: Layout) -> Result<()>
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. SeeLayout
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:
Error::NoSource
- no source was specified for this arena.Error::AllocatorError
- the allocator could not allocate a boundary tag to support this span.
sourcepub fn alloc(&self, size: usize, policy: AllocPolicy) -> Result<usize>
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. SeeAllocPolicy
for more details.
§Returns
If a block could not be allocated, one of the following errors will be returned:
Error::Empty
- the arena is empty, and no source was specified to borrow from.Error::AllocatorError
- the allocator could not allocate a boundary tag to support this block.Error::AllocZeroSize
- the requested allocation has no size.
If a source is specified, this function will forward any errors given by it.
sourcepub fn xalloc(&self, layout: Layout, policy: AllocPolicy) -> Result<usize>
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. SeeAllocPolicy
for more details.
§Returns
If a block could not be allocated, one of the following errors will be returned:
Error::Empty
- the arena is empty, and no source was specified to borrow from.Error::AllocatorError
- the allocator could not allocate a boundary tag to support this block.Error::AllocZeroSize
- the requested allocation has no size.
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.
sourcepub fn free(&self, base: usize) -> Result<()>
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:
Error::NoSuchAllocation
- the block was not allocated by this arena, or was already freed.
sourcepub fn total_space(&self) -> usize
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.
sourcepub fn allocated_space(&self) -> usize
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.
sourcepub fn free_space(&self) -> usize
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.
sourcepub fn borrowed_space(&self) -> usize
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.