pub struct Arena { /* private fields */ }Expand description
Basic Arena Allocator that uses the crate memmap2 to request wholesale allocation of memory from
the system.
An arena is a memory management strategy in which you request a chunk of memory upfront and use it to allocate many objects in sequence. Essentially, it turns memory allocation from a heap problem into a stack problem increasing the speed of this process. It is a technique common in the video game industry to minimize the time spent asking the system for allocations.
Here we offer this small implementation to help speed up parsing operations in other RUMTK crates.
This is a standalone crate with no dependencies on other RUMTK crates.
Another feature is that we implement the Allocator trait thus allowing you to provide an instance
of the Arena to other standard collections through the nightly compiler’s allocator_api feature.
Note that this feature is considered unstable.
§Safety
- Calling
resetsimply resets the pointer to 0 and thus technically allows for the potential to leak a prior round of work’s information if a pointer return byallocateis misused. - No calls to drop are invoked!!! You have to find a different way to manually do so. This implementation is meant to deal with quick allocation needs and not with self managed resources for which a RAII approach might be more appropriate.
§Example
§Simple initialization and Writing of value.
use crate::rumtk_arena::Arena;
let mut arena = Arena::with_capacity(size_of::<usize>() * 1);
let result_ptr = arena.write(5);
Implementations§
Source§impl Arena
impl Arena
Sourcepub fn new() -> Arena
pub fn new() -> Arena
Allocates a new Arena using the DEFAULT_ARENA_MEMORY_ALLOCATION allocation size.
Sourcepub fn with_capacity(capacity: usize) -> Arena
pub fn with_capacity(capacity: usize) -> Arena
Allocates new Arena with the specified size. At the moment, we use the memmap2 crate’s defaults
for this allocation.
pub const fn null() -> Arena
pub fn from_parts(ptr: *mut u8, capacity: usize, dealloc: bool) -> Arena
pub fn split_to(&mut self, len: usize) -> Arena
pub fn freeze(&mut self) -> Arena
pub fn remaining(&self) -> usize
pub fn capacity(&self) -> usize
Sourcepub fn can_allocate(&self, size: usize) -> bool
pub fn can_allocate(&self, size: usize) -> bool
Checks if it is possible to allocate the next object. This is an assertion guarded operation and will
panic!!!!!!!
Sourcepub fn commit(&mut self, size: usize) -> Result<*mut [u8], AllocError>
pub fn commit(&mut self, size: usize) -> Result<*mut [u8], AllocError>
Commits a chunk of memory from our memory pool.
§Safety
We call Self::can_allocate to assert that the size requested does not exceed the total
pool available. panic if we do not have enough memory to commit.
Sourcepub fn write_bytes(
&mut self,
src: *const u8,
data_length: usize,
) -> Result<*mut [u8], AllocError>
pub fn write_bytes( &mut self, src: *const u8, data_length: usize, ) -> Result<*mut [u8], AllocError>
Writes a number of bytes into a pre allocated segment from our pool.
Sourcepub fn write<T>(&mut self, data: T) -> Result<NonNull<T>, AllocError>
pub fn write<T>(&mut self, data: T) -> Result<NonNull<T>, AllocError>
Commits a type object into the memory advancing the internal cursor.
§Order of Operations
- Calculate size of object.
- Commit a chunk of memory via Self::commit.
- Cast object to a byte pointer.
- Memcopy from
srctodstby the number of bytes calculated in #1.
§Safety
We call Self::commit first before applying a memcopy. Self::commit can panic if there is a bug in
this crate due to our call of assert!
Panics if casting to non null pointer somehow fails.
Sourcepub fn uncommit(&mut self, length: usize)
pub fn uncommit(&mut self, length: usize)
We do not truly drop objects. Instead, we move the cursor back by the requested number of bytes.
§Safety
Note that this means old results remain valid and could accidentally end up in a new allocation that could be safety sensitive.