Skip to main content

SlabAllocator

Struct SlabAllocator 

Source
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 to RawMutex).
  • 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>

Source

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_list
  • slab_list
  • slab_count
  • obj_count
  • max_obj_count
  • max_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>

Source

pub fn lock_mu( &self, ) -> impl PinInit<SlabAllocatorMuGuard<'_, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>, Infallible>

Source

pub fn lock_mu_policy<P: LockPolicy<RawMutex, AcquireArgs = ()>>( &self, ) -> impl PinInit<SlabAllocatorMuGuard<'_, T, L, SLAB_SIZE, TRACK_OBJECT_COUNT, P>, Infallible>

Source

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>

Source

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>

Source

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>

Source

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>

Source

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.

Source

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.

Source

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>

Source

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>

Source

pub const ALLOC_ALIGN: usize

Source

pub const ALLOC_SIZE: usize

Source

pub const STORAGE_OFFSET: usize

Source

pub const ALLOCS_PER_SLAB: usize

The number of objects of type T that can fit in a single slab.

Source

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.

Source

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.

Source

pub fn init(max_slabs: usize) -> impl PinInit<Self, Infallible>

Creates a new PinInit initializer for SlabAllocator for dynamic initialization.

Source

pub fn alloc_raw(&self) -> Result<NonNull<T>, AllocError>

Allocates raw, uninitialized memory for a single object of type T.

Source

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.

Source

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.

Source

pub fn new_ref(&self, value: T) -> Result<RefPtr<T>, AllocError>
where T: HasRefCount + Recyclable + InstancedSlabAllocated<L, SLAB_SIZE, TRACK_OBJECT_COUNT>,

Constructs a ref-counted object in a RefPtr using memory allocated from this instanced allocator.

Source

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.

Source

pub fn obj_count(&self) -> usize

Returns the number of currently allocated objects.

Source

pub fn max_obj_count(&self) -> usize

Returns the maximum number of objects allocated simultaneously over the life of the allocator.

Source

pub fn slab_count(&self) -> usize

Returns the number of slabs allocated.

Source

pub fn max_slabs(&self) -> usize

Returns the maximum number of slabs this allocator is allowed to allocate.

Source

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>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
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>

Source§

type PinData = __ThePinData<T, L, SLAB_SIZE, TRACK_OBJECT_COUNT>

Source§

unsafe fn __pin_data() -> Self::PinData

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>

Source§

fn drop(self: Pin<&mut Self>, _: OnlyCallFromDrop)

Executes the pinned destructor of this type. Read more
Source§

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>

Source§

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 T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Init<T> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), !>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
§

impl<T, U> Into<U> for T
where U: From<T>,

§

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> PinInit<T> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), !>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

impl<T> ToMutPtr for T
where T: ?Sized,

Source§

type Target = T

The target type of the pointer.
Source§

fn to_mut_ptr(&self) -> *mut T

Casts the reference to a mutable raw pointer.
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = !

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

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.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.