cannon_heap/
lib.rs

1#![no_std]
2///! This is actually just a wrapper around linked_list_allocator that allows it to work in our environment
3///! Different allocator can be used if desired
4use core::alloc::{GlobalAlloc, Layout};
5use core::cell::RefCell;
6use core::mem::MaybeUninit;
7use core::ptr::{self, NonNull};
8struct Alloc {
9    heap: RefCell<linked_list_allocator::Heap>,
10}
11
12impl Alloc {
13    const fn new() -> Self {
14        Self {
15            heap: RefCell::new(linked_list_allocator::Heap::empty()),
16        }
17    }
18}
19
20unsafe impl GlobalAlloc for Alloc {
21    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
22        self.heap
23            .borrow_mut()
24            .allocate_first_fit(layout)
25            .ok()
26            .map_or(ptr::null_mut(), |allocation| allocation.as_ptr())
27    }
28
29    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
30        self.heap
31            .borrow_mut()
32            .deallocate(NonNull::new_unchecked(ptr), layout)
33    }
34}
35
36#[global_allocator]
37static mut ALLOCATOR: Alloc = Alloc::new();
38
39pub unsafe fn init(heap: &mut [MaybeUninit<u8>]) {
40    ALLOCATOR
41        .heap
42        .borrow_mut()
43        .init(heap.as_mut_ptr() as *mut u8, heap.len())
44}
45
46#[macro_export]
47macro_rules! init_heap {
48    ( $x:expr ) => {{
49        use cannon_heap::init;
50        use core::mem::MaybeUninit;
51        static mut HEAP: [MaybeUninit<u8>; $x] = [MaybeUninit::uninit(); $x];
52        unsafe { init(&mut HEAP) }
53    }};
54}