@@ -12,3 +12,58 @@ mod tlsf;
12
12
pub use llff:: Heap as LlffHeap ;
13
13
#[ cfg( feature = "tlsf" ) ]
14
14
pub use tlsf:: Heap as TlsfHeap ;
15
+
16
+ /// Initialize the global heap.
17
+ ///
18
+ /// This macro creates a static, uninitialized memory buffer of the specified size and
19
+ /// initializes the heap instance with that buffer.
20
+ ///
21
+ /// # Parameters
22
+ ///
23
+ /// - `$heap:ident`: The identifier of the global heap instance to initialize.
24
+ /// - `$size:expr`: An expression evaluating to a `usize` that specifies the size of the
25
+ /// static memory buffer in bytes. It must be **greater than zero**.
26
+ ///
27
+ /// # Safety
28
+ ///
29
+ /// This macro must be called first, before any operations on the heap, and **only once**.
30
+ ///
31
+ /// # Example
32
+ ///
33
+ /// ```rust
34
+ /// use cortex_m_rt::entry;
35
+ /// use embedded_alloc::LlffHeap as Heap;
36
+ ///
37
+ /// #[global_allocator]
38
+ /// static HEAP: Heap = Heap::empty();
39
+ ///
40
+ /// #[entry]
41
+ /// fn main() -> ! {
42
+ /// // Initialize the allocator BEFORE you use it
43
+ /// embedded_alloc::init!(HEAP, 1024);
44
+ /// let mut xs = Vec::new();
45
+ /// // ...
46
+ /// }
47
+ /// ```
48
+ #[ macro_export]
49
+ macro_rules! init {
50
+ ( $heap: ident, $size: expr) => {
51
+ assert!( $size > 0 ) ;
52
+ // Ensure the heap is static.
53
+ let static_heap: & ' static Heap = & $heap;
54
+
55
+ use core:: sync:: atomic:: AtomicBool ;
56
+ use core:: sync:: atomic:: Ordering ;
57
+ // Ensure it is called only once.
58
+ static CALL_ONCE : AtomicBool = AtomicBool :: new( false ) ;
59
+ assert_eq!( CALL_ONCE . load( Ordering :: Acquire ) , false ) ;
60
+ CALL_ONCE . store( true , Ordering :: Release ) ;
61
+
62
+ static mut HEAP_MEM : [ core:: mem:: MaybeUninit <u8 >; $size] =
63
+ [ core:: mem:: MaybeUninit :: uninit( ) ; $size] ;
64
+ unsafe {
65
+ #[ allow( static_mut_refs) ]
66
+ $heap. init( & raw mut HEAP_MEM as usize , $size)
67
+ }
68
+ } ;
69
+ }
0 commit comments