/ src / allocator / bump.rs
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