stm32f1_hal/common/
simplest_heap.rs1use core::alloc::{GlobalAlloc, Layout};
2use core::cell::{Cell, RefCell};
3use core::ptr;
4use critical_section::Mutex;
5
6pub struct Heap {
15 heap: Mutex<RefCell<SimplestHeap>>,
16 once_flag: Mutex<Cell<bool>>,
17}
18
19impl Heap {
20 pub const fn empty() -> Heap {
25 Heap {
26 heap: Mutex::new(RefCell::new(SimplestHeap::empty())),
27 once_flag: Mutex::new(Cell::new(false)),
28 }
29 }
30
31 pub unsafe fn init(&self, start_addr: usize, size: usize) {
47 assert!(size > 0);
48 critical_section::with(|cs| {
49 let once_flag = self.once_flag.borrow(cs);
50 assert!(!once_flag.get());
51 once_flag.set(true);
52
53 self.heap
54 .borrow(cs)
55 .borrow_mut()
56 .init(start_addr as *mut u8, size);
57 });
58 }
59
60 pub fn used(&self) -> usize {
62 critical_section::with(|cs| self.heap.borrow(cs).borrow().used())
63 }
64
65 pub fn free(&self) -> usize {
67 critical_section::with(|cs| self.heap.borrow(cs).borrow().free())
68 }
69}
70
71unsafe impl GlobalAlloc for Heap {
72 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
73 critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().alloc(layout))
74 }
75
76 unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
77}
78
79struct SimplestHeap {
80 arena: *mut u8,
81 remaining: usize,
82 size: usize,
83}
84
85unsafe impl Send for SimplestHeap {}
86
87impl SimplestHeap {
88 const fn empty() -> Self {
89 Self {
90 arena: ptr::null_mut(),
91 remaining: 0,
92 size: 0,
93 }
94 }
95
96 fn init(&mut self, start_addr: *mut u8, size: usize) {
97 self.arena = start_addr;
98 self.remaining = size;
99 self.size = size;
100 }
101
102 fn free(&self) -> usize {
103 self.remaining
104 }
105
106 fn used(&self) -> usize {
107 self.size - self.remaining
108 }
109
110 fn alloc(&mut self, layout: Layout) -> *mut u8 {
111 if layout.size() > self.remaining {
112 return ptr::null_mut();
113 }
114
115 let align_mask_to_round_down = !(layout.align() - 1);
118
119 self.remaining -= layout.size();
120 self.remaining &= align_mask_to_round_down;
121 self.arena.wrapping_add(self.remaining)
122 }
123}