bump.rs
1 use super::{align_up, Locked}; 2 use alloc::alloc::{GlobalAlloc, Layout}; 3 use core::ptr; 4 5 pub struct BumpAllocator { 6 heap_start: usize, 7 heap_end: usize, 8 next: usize, 9 allocations: usize, 10 } 11 12 impl BumpAllocator { 13 pub const fn new() -> Self { 14 BumpAllocator { 15 heap_start: 0, 16 heap_end: 0, 17 next: 0, 18 allocations: 0, 19 } 20 } 21 22 pub unsafe fn init(&mut self, heap_start: usize, heap_size: usize) { 23 self.heap_start = heap_start; 24 self.heap_end = heap_start + heap_size; 25 self.next = heap_start; 26 } 27 } 28 29 unsafe impl GlobalAlloc for Locked<BumpAllocator> { 30 unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 31 let mut bump = self.lock(); 32 33 let alloc_start = align_up(bump.next, layout.align()); 34 let alloc_end = match alloc_start.checked_add(layout.size()) { 35 Some(end) => end, 36 None => return ptr::null_mut(), 37 }; 38 39 if alloc_end > bump.heap_end { 40 ptr::null_mut() 41 } else { 42 bump.next = alloc_end; 43 bump.allocations += 1; 44 alloc_start as *mut u8 45 } 46 } 47 48 unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) { 49 let mut bump = self.lock(); 50 51 bump.allocations -= 1; 52 if bump.allocations == 0 { 53 bump.next = bump.heap_start; 54 } 55 } 56 } 57