Skip to main content

BumpAllocator

Struct BumpAllocator 

Source
pub struct BumpAllocator { /* private fields */ }
Expand description

A thread-safe, lock-free bump allocator backed by a static byte buffer.

Allocations are fulfilled by atomically advancing an internal offset; no individual deallocation is possible. Call reset (or reset_zeroed) to reclaim the entire buffer at once.

§Thread Safety

BumpAllocator is Sync + Send. Concurrent alloc calls use a compare-and-swap loop to guarantee each thread receives a non-overlapping slice of the backing buffer.

§Invariants

  • start always points to the first byte of the backing buffer.
  • 0 <= offset <= size at all times.
  • Memory in [start, start + offset) has been “handed out” and must not be written by the allocator itself until reset is called.

Implementations§

Source§

impl BumpAllocator

Source

pub fn new(buf: &'static mut [u8]) -> Self

Creates a new bump allocator that owns the given static buffer.

The buffer must outlive the allocator (enforced by the 'static bound).

§Example
static mut BUF: [u8; 65536] = [0u8; 65536];
let bump = BumpAllocator::new(unsafe { &mut BUF });
Examples found in repository?
examples/bump_stack.rs (line 11)
8fn get_bump() -> &'static Mutex<BumpAllocator> {
9    BUMP.get_or_init(|| {
10        let buffer = Box::leak(vec![0u8; 1024].into_boxed_slice());
11        Mutex::new(BumpAllocator::new(buffer))
12    })
13}
Source

pub fn used(&self) -> usize

Returns the number of bytes that have been allocated from the buffer.

Examples found in repository?
examples/bump_stack.rs (line 26)
15fn main() {
16    let bump_mutex = get_bump();
17    let mut bump = bump_mutex.lock().unwrap();
18
19    {
20        let mut stack_vec = ExVec::new(&*bump);
21        
22        stack_vec.push(10);
23        stack_vec.push(20);
24        stack_vec.push(30);
25
26        println!("Bump usage: {}/1024", bump.used());
27    } 
28
29    bump.reset();
30    
31    println!("Bump reset. Usage: {}", bump.used());
32}
Source

pub fn remaining(&self) -> usize

Returns the number of bytes still available for allocation.

Source

pub fn capacity(&self) -> usize

Returns the total capacity of the backing buffer in bytes.

Source

pub fn reset(&mut self)

Resets the allocator, making the entire buffer available again.

§Safety

All pointers previously returned by alloc or alloc_slice become invalid after this call. Any subsequent access to those pointers is undefined behaviour.

Examples found in repository?
examples/bump_stack.rs (line 29)
15fn main() {
16    let bump_mutex = get_bump();
17    let mut bump = bump_mutex.lock().unwrap();
18
19    {
20        let mut stack_vec = ExVec::new(&*bump);
21        
22        stack_vec.push(10);
23        stack_vec.push(20);
24        stack_vec.push(30);
25
26        println!("Bump usage: {}/1024", bump.used());
27    } 
28
29    bump.reset();
30    
31    println!("Bump reset. Usage: {}", bump.used());
32}
Source

pub fn reset_zeroed(&mut self)

Resets the allocator and zero-fills the entire backing buffer with SIMD.

Useful when the buffer may contain sensitive data that should not persist.

§Safety

Same as reset: all previously returned pointers are invalidated.

Source

pub fn alloc_slice(&self, size: usize, align: usize) -> Option<&mut [u8]>

Allocates a mutable byte slice of size bytes with the given align.

Returns None if the remaining capacity is insufficient or if align is not a power of two.

§Example
let slice: &mut [u8] = bump.alloc_slice(64, 16).unwrap();

Trait Implementations§

Source§

impl Allocator for BumpAllocator

Source§

unsafe fn alloc(&self, layout: Layout) -> Option<NonNull<u8>>

Allocates a block satisfying layout from the backing buffer.

§Safety
  • layout.size() must be greater than zero.
  • The returned pointer is valid until reset is called or the allocator is dropped (though dropping does not invalidate the underlying 'static buffer).
Source§

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

No-op. Individual deallocation is not supported by a bump allocator.

Use reset to reclaim all memory at once.

§Safety

Even though this method is a no-op, callers must not use ptr after calling dealloc — doing so would be use-after-free once reset is eventually called.

Source§

impl Send for BumpAllocator

Source§

impl Sync for BumpAllocator

Auto Trait Implementations§

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