Struct static_alloc::unsync::Bump[][src]

#[repr(C)]
pub struct Bump<T> { /* fields omitted */ }
Expand description

A bump allocator whose storage capacity and alignment is given by T.

This type dereferences to the generic MemBump that implements the allocation behavior. Note that MemBump is an unsized type. In contrast this type is sized so it is possible to construct an instance on the stack or leak one from another bump allocator such as a global one.

Usage

For on-stack usage this works the same as Bump. Note that it is not possible to use as a global allocator though.

One interesting use case for this struct is as scratch space for subroutines. This ensures good locality and cache usage. It can also allows such subroutines to use a dynamic amount of space without the need to actually allocate. Contrary to other methods where the caller provides some preallocated memory it will also not ‘leak’ private data types. This could be used in handling web requests.

use static_alloc::unsync::Bump;

let mut stack_buffer: Bump<[usize; 64]> = Bump::uninit();
subroutine_one(&stack_buffer);
stack_buffer.reset();
subroutine_two(&stack_buffer);

Note that you need not use the stack for the Bump itself. Indeed, you could allocate a large contiguous instance from the global (synchronized) allocator and then do subsequent allocations from the Bump you’ve obtained. This avoids potential contention on a lock of the global allocator, especially in case you must do many small allocations. If you’re writing an allocator yourself you might use this technique as an internal optimization.

use static_alloc::unsync::{Bump, MemBump};
let mut local_page: Box<Bump<[u64; 64]>> = Box::new(Bump::uninit());

for request in iterate_recv() {
    local_page.reset();
    handle_request(&local_page, request);
}

Implementations

impl<T> Bump<T>[src]

pub fn uninit() -> Self[src]

Create an allocator with uninitialized memory.

All allocations coming from the allocator will need to be initialized manually.

pub fn zeroed() -> Self[src]

Create an allocator with zeroed memory.

The caller can rely on all allocations to be zeroed.

Methods from Deref<Target = MemBump>

pub fn alloc(&self, layout: Layout) -> Option<NonNull<u8>>[src]

Allocate a region of memory.

This is a safe alternative to GlobalAlloc::alloc.

Panics

This function will panic if the requested layout has a size of 0. For the use in a GlobalAlloc this is explicitely forbidden to request and would allow any behaviour but we instead strictly check it.

pub fn alloc_at(
    &self,
    layout: Layout,
    level: Level
) -> Result<NonNull<u8>, Failure>
[src]

Try to allocate some layout with a precise base location.

The base location is the currently consumed byte count, without correction for the alignment of the allocation. This will succeed if it can be allocate exactly at the expected location.

Panics

This function may panic if the provided level is from a different slab.

pub fn get<V>(&self) -> Option<Allocation<'_, V>>[src]

Get an allocation for a specific type.

It is not yet initialized but provides an interface for that initialization.

Usage

use core::cell::{Ref, RefCell};

let slab: Bump<[Ref<'static, usize>; 1]> = Bump::uninit();
let data = RefCell::new(0xff);

// We can place a `Ref` here but we did not yet.
let alloc = slab.get::<Ref<usize>>().unwrap();
let cell_ref = unsafe {
    alloc.leak(data.borrow())
};

assert_eq!(**cell_ref, 0xff);

pub fn get_at<V>(&self, level: Level) -> Result<Allocation<'_, V>, Failure>[src]

Get an allocation for a specific type at a specific level.

See get for usage.

pub fn bump_box<'bump, T: 'bump>(
    &'bump self
) -> Result<LeakBox<'bump, MaybeUninit<T>>, Failure>
[src]

Allocate space for one T without initializing it.

Note that the returned MaybeUninit can be unwrapped from LeakBox. Or you can store an arbitrary value and ensure it is safely dropped before the borrow ends.

Usage

use core::cell::RefCell;
use static_alloc::leaked::LeakBox;

let slab: Bump<[usize; 4]> = Bump::uninit();
let data = RefCell::new(0xff);

let slot = slab.bump_box().unwrap();
let cell_box = LeakBox::write(slot, data.borrow());

assert_eq!(**cell_box, 0xff);
drop(cell_box);

assert!(data.try_borrow_mut().is_ok());

pub fn bump_array<'bump, T: 'bump>(
    &'bump self,
    n: usize
) -> Result<LeakBox<'bump, [MaybeUninit<T>]>, Failure>
[src]

Allocate space for a slice of Ts without initializing any.

Retrieve individual MaybeUninit elements and wrap them as a LeakBox to store values. Or use the slice as backing memory for one of the containers from without-alloc. Or manually initialize them.

Usage

Quicksort, implemented recursively, requires a maximum of log n stack frames in the worst case when implemented optimally. Since each frame is quite large this is wasteful. We can use a properly sized buffer instead and implement an iterative solution. (Left as an exercise to the reader, or see the examples for without-alloc where we use such a dynamic allocation with an inline vector as our stack).

pub fn level(&self) -> Level[src]

Get the number of already allocated bytes.

pub fn reset(&mut self)[src]

Reset the bump allocator.

This requires a unique reference to the allocator hence no allocation can be alive at this point. It will reset the internal count of used bytes to zero.

Trait Implementations

impl<T> Deref for Bump<T>[src]

type Target = MemBump

The resulting type after dereferencing.

fn deref(&self) -> &MemBump[src]

Dereferences the value.

impl<T> DerefMut for Bump<T>[src]

fn deref_mut(&mut self) -> &mut MemBump[src]

Mutably dereferences the value.

Auto Trait Implementations

impl<T> Send for Bump<T> where
    T: Send

impl<T> !Sync for Bump<T>

impl<T> Unpin for Bump<T> where
    T: Unpin

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

pub fn type_id(&self) -> TypeId[src]

Gets the TypeId of self. Read more

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

pub fn borrow(&self) -> &T[src]

Immutably borrows from an owned value. Read more

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

pub fn borrow_mut(&mut self) -> &mut T[src]

Mutably borrows from an owned value. Read more

impl<T> From<T> for T[src]

pub fn from(t: T) -> T[src]

Performs the conversion.

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

pub fn into(self) -> U[src]

Performs the conversion.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

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

Performs the conversion.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

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

Performs the conversion.