pub struct SlabAllocator<T, L: RawLock + IsRawMutex = RawMutex, const SLAB_SIZE: usize = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE, const TRACK_OBJECT_COUNT: bool = false> { /* private fields */ }Expand description
A slab-style allocator for a given object type T.
§Generics
T: The type of object allocated by this allocator.L: The synchronization primitive (defaults toRawMutex).SLAB_SIZE: The size of each memory slab in bytes (defaults to 16KB).TRACK_OBJECT_COUNT: Enable allocation tracking (e.g.obj_count,max_obj_count).
§Examples
§Instanced Allocation with UniquePtr
use fbl::{
SlabAllocator, RawMutex, impl_instanced_slab_allocatable, UniquePtr,
DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE,
};
use core::cell::Cell;
use fbl::SlabOrigin;
struct MyObject {
value: i32,
// Required field for tracking origin
slab_origin: SlabOrigin<MyObject, RawMutex, DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE>,
}
impl_instanced_slab_allocatable!(MyObject, RawMutex, DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE);
fn example() {
let allocator = SlabAllocator::<
MyObject, RawMutex, DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE
>::try_new(4, true, RawMutex::INIT).unwrap();
let mut list = std::collections::VecDeque::new();
for i in 0..10 {
let obj = allocator.new_unique(MyObject {
value: i,
slab_origin: SlabOrigin::new(),
}).unwrap();
list.push_front(obj);
}
// Memory is automatically returned to the allocator when elements are dropped.
}§Static Allocation with UniquePtr
use fbl::{
SlabAllocator, RawMutex, impl_static_slab_allocatable, UniquePtr,
DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE
};
struct MyObject {
value: i32,
}
static MY_ALLOCATOR: SlabAllocator<MyObject, RawMutex, DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE> =
SlabAllocator::const_new(64, RawMutex::INIT);
impl_static_slab_allocatable!(
MyObject, RawMutex, DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE, MY_ALLOCATOR);
fn example() {
let obj = UniquePtr::try_new(MyObject { value: 42 }).unwrap();
// obj will automatically recycle back to MY_ALLOCATOR.
}Implementations§
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Sourcepub fn project<'__pin>(
self: Pin<&'__pin mut Self>,
) -> SlabAllocatorProjection<'__pin, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub fn project<'__pin>( self: Pin<&'__pin mut Self>, ) -> SlabAllocatorProjection<'__pin, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Pin-projects all fields of Self.
These fields are structurally pinned:
mu
These fields are not structurally pinned:
free_listslab_listslab_countobj_countmax_obj_countmax_slabs_phantom
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub fn lock_mu( &self, ) -> impl PinInit<SlabAllocatorMuGuard<'_, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>, Infallible>
pub fn lock_mu_policy<P: LockPolicy<RawMutex, AcquireArgs = ()>>( &self, ) -> impl PinInit<SlabAllocatorMuGuard<'_, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT, P>, Infallible>
pub fn lock_mu_aliased<'a, AliasClass: LockClass, M2: RawLock>( &'a self, alias: &'a KMutex<AliasClass, M2>, ) -> impl PinInit<KMutexAliasedGuard<'a, SlabAllocatorMuClass<T, L>, AliasClass, RawMutex, M2>, Infallible>
pub fn lock_mu_aliased_policy<'a, AliasClass: LockClass, M2: RawLock, P: LockPolicy<RawMutex, AcquireArgs = ()>>( &'a self, alias: &'a KMutex<AliasClass, M2>, ) -> impl PinInit<KMutexAliasedGuard<'a, SlabAllocatorMuClass<T, L>, AliasClass, RawMutex, M2, P>, Infallible>
pub fn lock_mu_multiple<'a, const __KSYNC_N: usize>( items: [&'a Self; __KSYNC_N], ) -> impl PinInit<KMutexGuardMultiple<'a, __KSYNC_N, SlabAllocatorMuClass<T, L>, RawMutex>, Infallible>
pub fn lock_mu_multiple_policy<'a, const __KSYNC_N: usize, P: LockPolicy<RawMutex, AcquireArgs = ()>>( items: [&'a Self; __KSYNC_N], ) -> impl PinInit<KMutexGuardMultiple<'a, __KSYNC_N, SlabAllocatorMuClass<T, L>, RawMutex, P>, Infallible>
Sourcepub unsafe fn guard_mu<'b, 'a>(
&'b self,
token: &'b LockToken<'a, SlabAllocatorMuClass<T, L>>,
) -> SlabAllocatorMuTokenGuard<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub unsafe fn guard_mu<'b, 'a>( &'b self, token: &'b LockToken<'a, SlabAllocatorMuClass<T, L>>, ) -> SlabAllocatorMuTokenGuard<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Creates a read-only token guard for accessing fields protected by this mutex.
§Safety
The caller must ensure that token belongs to the specific lock instance that
protects self.
Sourcepub unsafe fn guard_mu_mut<'b, 'a>(
&'b self,
token: &'b mut LockToken<'a, SlabAllocatorMuClass<T, L>>,
) -> SlabAllocatorMuTokenGuardMut<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub unsafe fn guard_mu_mut<'b, 'a>( &'b self, token: &'b mut LockToken<'a, SlabAllocatorMuClass<T, L>>, ) -> SlabAllocatorMuTokenGuardMut<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Creates a mutable token guard for accessing fields protected by this mutex.
§Safety
The caller must ensure that token belongs to the specific lock instance that
protects self and is not used to create aliasing references to self’s fields.
pub fn guard_mu_from_guard<'b, 'a, P: LockPolicy<RawMutex>>( &'b self, guard: &'b KMutexGuard<'a, SlabAllocatorMuClass<T, L>, RawMutex, P>, ) -> SlabAllocatorMuTokenGuard<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub fn guard_mu_mut_from_guard<'b, 'a, P: LockPolicy<RawMutex>>( &'b self, guard: Pin<&'b mut KMutexGuard<'a, SlabAllocatorMuClass<T, L>, RawMutex, P>>, ) -> SlabAllocatorMuTokenGuardMut<'b, 'a, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
pub const ALLOC_ALIGN: usize
pub const ALLOC_SIZE: usize
pub const STORAGE_OFFSET: usize
Sourcepub const ALLOCS_PER_SLAB: usize
pub const ALLOCS_PER_SLAB: usize
The number of objects of type T that can fit in a single slab.
Sourcepub fn preallocate(&self) -> Result<(), AllocError>
pub fn preallocate(&self) -> Result<(), AllocError>
Pre-allocates the first slab.
This can be used to guarantee O(1) execution times for all future allocations
if max_slabs is at least 1.
Sourcepub const fn const_new(max_slabs: usize, lock: RawMutex) -> Self
pub const fn const_new(max_slabs: usize, lock: RawMutex) -> Self
Creates a new SlabAllocator that can be initialized in const contexts.
Note: Slabs are not pre-allocated during const-construction.
Sourcepub fn init(max_slabs: usize) -> impl PinInit<Self, Infallible>
pub fn init(max_slabs: usize) -> impl PinInit<Self, Infallible>
Creates a new PinInit initializer for SlabAllocator for dynamic initialization.
Sourcepub fn alloc_raw(&self) -> Result<NonNull<T>, AllocError>
pub fn alloc_raw(&self) -> Result<NonNull<T>, AllocError>
Allocates raw, uninitialized memory for a single object of type T.
Sourcepub unsafe fn return_to_free_list(&self, ptr: NonNull<T>)
pub unsafe fn return_to_free_list(&self, ptr: NonNull<T>)
Returns raw memory to the free list.
§Safety
ptr must have been previously allocated from this allocator, and must not have
been returned already.
Sourcepub fn new_unique(&self, value: T) -> Result<UniquePtr<T>, AllocError>where
T: Recyclable + InstancedSlabAllocated<L, SLAB_SIZE, TRACK_OBJECT_COUNT>,
pub fn new_unique(&self, value: T) -> Result<UniquePtr<T>, AllocError>where
T: Recyclable + InstancedSlabAllocated<L, SLAB_SIZE, TRACK_OBJECT_COUNT>,
Constructs an object in a UniquePtr using memory allocated from this instanced allocator.
Sourcepub fn new_ref(&self, value: T) -> Result<RefPtr<T>, AllocError>
pub fn new_ref(&self, value: T) -> Result<RefPtr<T>, AllocError>
Constructs a ref-counted object in a RefPtr using memory allocated from this instanced
allocator.
Sourcepub unsafe fn delete(&self, ptr: NonNull<T>)
pub unsafe fn delete(&self, ptr: NonNull<T>)
Destructs and deallocates an unmanaged object.
§Safety
ptr must point to a valid object allocated from this allocator.
Sourcepub fn max_obj_count(&self) -> usize
pub fn max_obj_count(&self) -> usize
Returns the maximum number of objects allocated simultaneously over the life of the allocator.
Sourcepub fn slab_count(&self) -> usize
pub fn slab_count(&self) -> usize
Returns the number of slabs allocated.
Sourcepub fn max_slabs(&self) -> usize
pub fn max_slabs(&self) -> usize
Returns the maximum number of slabs this allocator is allowed to allocate.
Sourcepub fn reset_max_obj_count(&self)
pub fn reset_max_obj_count(&self)
Resets the maximum object count tracker to the current object count.
Trait Implementations§
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> Drop for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> Drop for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> HasPinData for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> HasPinData for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Source§impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> PinnedDrop for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> PinnedDrop for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex + Send, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> Send for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L: RawLock + IsRawMutex + Sync, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> Sync for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Auto Trait Implementations§
impl<T, L = RawMutex, const SLAB_SIZE: usize = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE, const TRACK_OBJECT_COUNT: bool = false> !Freeze for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L = RawMutex, const SLAB_SIZE: usize = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE, const TRACK_OBJECT_COUNT: bool = false> !RefUnwindSafe for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L = RawMutex, const SLAB_SIZE: usize = DEFAULT_SLAB_ALLOCATOR_SLAB_SIZE, const TRACK_OBJECT_COUNT: bool = false> !UnwindSafe for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
impl<T, L, const SLAB_SIZE: usize, const TRACK_OBJECT_COUNT: bool> UnsafeUnpin for SlabAllocator<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, U> Into<U> for Twhere
U: From<T>,
impl<T, U> Into<U> for Twhere
U: From<T>,
Source§impl<T> PinInit<T> for T
impl<T> PinInit<T> for T
Source§unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), !>
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), !>
slot. Read moreSource§fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>where
F: FnOnce(Pin<&mut T>) -> Result<(), E>,
fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>where
F: FnOnce(Pin<&mut T>) -> Result<(), E>,
self then calls the function f with the initialized
value. Read more