1#![no_std]
2use 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}