Skip to main content

WithAllocationInfo

Struct WithAllocationInfo 

Source
pub struct WithAllocationInfo<A> { /* private fields */ }
Expand description

Wrapper around an allocator, that gathers stats about the underlying store while allocating.

The allocator_api2 design intentionally avoids generics in its result types. Allocations in the bump arena however provide some auxiliary information such as the usage level of the bump before and after an allocation (at least a snapshot of it for a Sync allocator). This information can be especially useful in case of an allocation failure but gather it separately would be racy. Allocating with this wrapper avoids the race.

For these use cases you can replace the allocator handle with this wrapper. The wrapper is equivalent to the underlying allocator.

§Usage

use static_alloc::allocator_api2::WithAllocationInfo;
use static_alloc::bump::Bump;

§Design

Interestingly, we could also provide per-call allocator configuration. For a Bump shared between threads for instance there is an inner loop around a fallible CAS. A parameter could constrain this loop to exit early on a case-by-case basis. It does not make too much sense to enforce it for all allocations in the arena. You would often prefer to use a non-racy thread-local arena in those cases (please open an issue if you have a use case). A handle wrapper on the other hand would provide surgical amounts of control.

Implementations§

Source§

impl<'lt, A: ?Sized> WithAllocationInfo<&'lt A>

Source

pub fn new(arena: &'lt A) -> Self

Wrap an arena to gather stats.

This does not constrain the type A. However, it can only be sensibly used with a Bump or BumpSlice or the unsync BumpSlice. It does not work with unsync’s Bump due to current design differences. (It is implemented with Deref into a BumpSlice instead of a view used for both. This will post-monomorphization error which we do not want to hide).

Source§

impl<A> WithAllocationInfo<A>

Source

pub fn last_observed_level(&self) -> Level

Query the consumed level observed by the last allocation call.

The value is updated both on success and failure.

§Usage

You will get information about the consumed bytes with each attempted allocation.

use static_alloc::allocator_api2::WithAllocationInfo;
use static_alloc::bump::Bump;
use allocator_api2::vec::Vec;

let arena =  Bump::<[usize; 4]>::uninit();
let hdl = WithAllocationInfo::new(&arena);

let mut vec = Vec::<u32, _>::with_capacity_in(1, hdl);
assert_eq!(vec.allocator().last_observed_level().byte_offset(), 4);

// This will not fit, and fail to allocate.
vec.try_reserve(32);
assert_eq!(vec.allocator().last_observed_level().byte_offset(), 4);

// This will, reallocating the vector.
vec.try_reserve_exact(2);
assert_eq!(vec.allocator().last_observed_level().byte_offset(), 12);

The information is updated also when the arena is used concurrently for another purpose, too.

use static_alloc::allocator_api2::WithAllocationInfo;
use static_alloc::bump::Bump;
use allocator_api2::vec::Vec;

let arena =  Bump::<[usize; 4]>::uninit();
let hdl = WithAllocationInfo::new(&arena);

let mut vec = Vec::<u32, _>::new_in(hdl);
let _ = arena.leak(0u32);

// Afterwards exactly three `u32` allocator, the one leaked and the 2 reserved.
vec.try_reserve_exact(2);
assert_eq!(vec.allocator().last_observed_level().byte_offset(), 12);
Source

pub fn last_allocation_start(&self) -> Level

Get the Level at which the last successful allocation sits.

This is provided for all allocations, sized and unsized.

§Usage
use static_alloc::allocator_api2::WithAllocationInfo;
use static_alloc::bump::Bump;
use allocator_api2::vec::Vec;

let arena =  Bump::<[usize; 4]>::uninit();
let hdl = WithAllocationInfo::new(&arena);

let mut vec = Vec::<u32, _>::with_capacity_in(1, hdl);
assert_eq!(vec.allocator().last_allocation_start().byte_offset(), 0);

// This will reallocate the vector, after the previous one.
vec.try_reserve_exact(2);
assert_eq!(vec.allocator().last_allocation_start().byte_offset(), 4);

Trait Implementations§

Source§

impl<T> Allocator for WithAllocationInfo<&Bump<T>>

Source§

fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Attempts to allocate a block of memory. Read more
Source§

unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout)

Deallocates the memory referenced by ptr. Read more
Source§

unsafe fn shrink( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to shrink the memory block. Read more
Source§

fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Behaves like allocate, but also ensures that the returned memory is zero-initialized. Read more
Source§

unsafe fn grow( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to extend the memory block. Read more
Source§

unsafe fn grow_zeroed( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Behaves like grow, but also ensures that the new contents are set to zero before being returned. Read more
Source§

fn by_ref(&self) -> &Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Allocator. Read more
Source§

impl Allocator for WithAllocationInfo<&BumpSlice>

Source§

fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Attempts to allocate a block of memory. Read more
Source§

unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout)

Deallocates the memory referenced by ptr. Read more
Source§

unsafe fn shrink( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to shrink the memory block. Read more
Source§

fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Behaves like allocate, but also ensures that the returned memory is zero-initialized. Read more
Source§

unsafe fn grow( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to extend the memory block. Read more
Source§

unsafe fn grow_zeroed( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Behaves like grow, but also ensures that the new contents are set to zero before being returned. Read more
Source§

fn by_ref(&self) -> &Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Allocator. Read more
Source§

impl Allocator for WithAllocationInfo<&BumpSlice>

Source§

fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Attempts to allocate a block of memory. Read more
Source§

unsafe fn deallocate(&self, _: NonNull<u8>, _: Layout)

Deallocates the memory referenced by ptr. Read more
Source§

unsafe fn shrink( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to shrink the memory block. Read more
Source§

fn allocate_zeroed(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError>

Behaves like allocate, but also ensures that the returned memory is zero-initialized. Read more
Source§

unsafe fn grow( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Attempts to extend the memory block. Read more
Source§

unsafe fn grow_zeroed( &self, ptr: NonNull<u8>, old_layout: Layout, new_layout: Layout, ) -> Result<NonNull<[u8]>, AllocError>

Behaves like grow, but also ensures that the new contents are set to zero before being returned. Read more
Source§

fn by_ref(&self) -> &Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Allocator. Read more

Auto Trait Implementations§

§

impl<A> !Freeze for WithAllocationInfo<A>

§

impl<A> !RefUnwindSafe for WithAllocationInfo<A>

§

impl<A> !Sync for WithAllocationInfo<A>

§

impl<A> Send for WithAllocationInfo<A>
where A: Send,

§

impl<A> Unpin for WithAllocationInfo<A>
where A: Unpin,

§

impl<A> UnsafeUnpin for WithAllocationInfo<A>
where A: UnsafeUnpin,

§

impl<A> UnwindSafe for WithAllocationInfo<A>
where A: UnwindSafe,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where 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, U> Into<U> for T
where 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 T
where U: Into<T>,

Source§

type Error = !

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

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

Performs the conversion.
Source§

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

Source§

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.