pub struct MnemosAlloc<U> {
    allocator: U,
    heap_size: AtomicUsize,
    stats: Stats,
}
Expand description

Mnemos Allocator

This is a wrapper type over an implementor of UnderlyingAllocator.

This “inherits” any of the behaviors and safety requirements of the chosen UnderlyingAllocator, and in addition has two major special behaviors that are intended to help respond gracefully to ephemeral Out of Memory conditions

  • On alloc:
    • We check whether allocation is inhibited. If it is - a nullptr is returned, regardless of whether there is sufficient room to allocate the requested amount.
    • If we are NOT inhibited, but are now out of memory (the underlying allocator returned a nullptr), we inhibit further allocations until the next deallocation occurs
  • On dealloc:
    • The “inhibit allocations” flag is cleared
    • If any tasks are waiting on the “OOM” queue, they are ALL awoken if the inhibit flag was previously set

These two details are intended to allow the “async allocation aware” types defined in crate::containers to yield if allocation is not currently possible.

By wrapping the UnderlyingAllocator, we allow non-async-aware allocations (like those through alloc::alloc::alloc() or alloc::alloc::dealloc()) to trigger these behaviors. However, non-async-aware allocations are still subject to normal OOM handling, which typically means panicking.

Fields§

§allocator: U§heap_size: AtomicUsize

The total size of the heap, in bytes.

§stats: Stats
Available on crate feature stats only.

Tracks heap statistics.

Implementations§

source§

impl<U> MnemosAlloc<U>

source

pub fn state(&self) -> State

Available on crate feature stats only.

Returns a snapshot of the current state of the heap.

This returns a struct containing all available heap metrics at the current point in time. It permits calculating derived metrics, such as State::free_bytes, State::alloc_attempt_count, and State::live_alloc_count, which are calculated using the values of other heap statistics.

Taking a single snapshot ensures that no drift occurs between these metrics. For example, if we were to call Self::alloc_success_count(), and then later attempt to calculate the number of live allocations by subtracting the value of Self::dealloc_count() from a subsequent call to Self::alloc_success_count(), additional concurrent allocations may have occurred between the first time the success count was loaded and the second. Taking one snapshot of all metrics ensures that no drift occurs, because the snapshot contains all heap metrics at the current point in time.

source

pub fn allocated_bytes(&self) -> usize

Available on crate feature stats only.

Returns the total amount of memory currently allocated, in bytes.

source

pub fn total_bytes(&self) -> usize

Available on crate feature stats only.

Returns the total size of the heap, in bytes. This includes memory that is currently allocated.

source

pub fn alloc_success_count(&self) -> usize

Available on crate feature stats only.

Returns the total number of times an allocation attempt has succeeded, over the lifetime of this heap.

source

pub fn alloc_oom_count(&self) -> usize

Available on crate feature stats only.

Returns the total number of times an allocation attempt could not be fulfilled because there was insufficient space, over the lifetime of this heap.

source

pub fn dealloc_count(&self) -> usize

Available on crate feature stats only.

Returns the total number of times an allocation has been deallocated, over the lifetime of this heap.

source§

impl<U: UnderlyingAllocator> MnemosAlloc<U>

source

const INITIALIZING: usize = 18_446_744_073_709_551_615usize

source

pub const fn new() -> Self

source

pub unsafe fn init( &self, start: NonNull<u8>, len: usize ) -> Result<(), InitError>

Initialize the allocator, with a heap of size len starting at start.

Returns
Safety

This function requires the caller to uphold the following invariants:

  • The memory region starting at start and ending at start + len may not be accessed except through pointers returned by this allocator.
  • The end of the memory region (start + len) may not exceed the physical memory available on the device.
  • The memory region must not contain memory regions used for memory-mapped IO.
source

pub fn total_size(&self) -> usize

Returns the total size of the heap in bytes, including allocated space.

The current free space remaining can be calculated by subtracting this value from [self.allocated_size()].

Trait Implementations§

source§

impl<U: UnderlyingAllocator> GlobalAlloc for MnemosAlloc<U>

source§

unsafe fn alloc(&self, layout: Layout) -> *mut u8

Allocate memory as described by the given layout. Read more
source§

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout)

Deallocate the block of memory at the given ptr pointer with the given layout. Read more
1.28.0 · source§

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8

Behaves like alloc, but also ensures that the contents are set to zero before being returned. Read more
1.28.0 · source§

unsafe fn realloc( &self, ptr: *mut u8, layout: Layout, new_size: usize ) -> *mut u8

Shrink or grow a block of memory to the given new_size in bytes. The block is described by the given ptr pointer and layout. Read more

Auto Trait Implementations§

§

impl<U> RefUnwindSafe for MnemosAlloc<U>where U: RefUnwindSafe,

§

impl<U> Send for MnemosAlloc<U>where U: Send,

§

impl<U> Sync for MnemosAlloc<U>where U: Sync,

§

impl<U> Unpin for MnemosAlloc<U>where U: Unpin,

§

impl<U> UnwindSafe for MnemosAlloc<U>where U: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

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

source§

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, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

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

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

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more