[−][src]Module alloc_compose::region
Stack-based allocators with user-provided memory
A region allocator allocates memory straight from one contiguous chunk. There is no
deallocation, and once the region is full, allocation requests returns AllocError
.
A region only stores a reference to the provided memory and a pointer to the current position.
This module provides three kinds of stack-based allocators: Region
, SharedRegion
, and
IntrusiveRegion
. All three allocators uses a user-provided memory to allocate and differ
in the way how they store the pointer to the current position.
Which region allocator to chose?
Every region allocator is more or less on-par. They slightly differ in performance depending on how many allocations are made and how big the allocations are.
Region
stores a current position in aCell
right next to the reference to the memory.SharedRegion
wraps theCell
in aRC
to support cloning of the allocator.IntrusiveRegion
stores the pointer to the current position at the end of the provided memory block.
This results in the fact, that Region
cannot be cloned. However, using AllocRef::by_ref
returns a reference to the region, which can itself be cloned.
SharedRegion
and IntrusiveRegion
both can be cloned. The IntrusiveRegion
has a
better performance in most cases due to cache coherence, but it's hard to say exactly, how much
capacity the allocator will have exactly, as the pointer to the current position has to be well
aligned. If this feature is important, SharedRegion
or Region
should be used instead.
SharedRegion
is only available with the alloc
-feature, as it requires the Rc
to
allocate memory to store the pointer in.
Examples
#![feature(allocator_api)] use alloc_compose::{region::Region, Owns}; use core::{ alloc::{AllocRef, Layout}, mem::MaybeUninit, }; let mut data = [MaybeUninit::uninit(); 64]; let region = Region::new(&mut data); let memory = region.alloc(Layout::new::<u32>())?; assert!(region.owns(memory));
This allocator can also be used in collection types of the std-library:
#![feature(nonnull_slice_from_raw_parts)] use core::ptr::NonNull; let mut vec: Vec<u32, _> = Vec::new_in(region.by_ref()); vec.extend(&[10, 20, 30]); assert_eq!(vec, [10, 20, 30]); let ptr = unsafe { NonNull::new_unchecked(vec.as_mut_ptr()) }; let memory = NonNull::slice_from_raw_parts(ptr.cast(), 12); assert!(region.owns(memory));
To reset the allocator, AllocateAll::deallocate_all
may be used:
use alloc_compose::AllocateAll; assert!(!region.is_empty()); region.deallocate_all(); assert!(region.is_empty());
Modules
raw | Region implementations which are not bound by a lifetime. |
Structs
IntrusiveRegion | An intrusive region allocator, which stores the current posision in the provided memory. |
Region | A stack allocator over an user-defined region of memory. |
SharedRegion | alloc A clonable region allocator based on |