8
8
//! extern crate collections;
9
9
//!
10
10
//! use collections::Vec;
11
+ //! use alloc_cortex_m::CortexMHeap;
12
+ //!
13
+ //! #[global_allocator]
14
+ //! static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
11
15
//!
12
16
//! // These symbols come from a linker script
13
17
//! extern "C" {
18
22
//! #[no_mangle]
19
23
//! pub fn main() -> ! {
20
24
//! // Initialize the heap BEFORE you use the allocator
21
- //! unsafe { alloc_cortex_m:: init(&mut _heap_start, &mut _heap_end) }
25
+ //! unsafe { ALLOCATOR. init(_heap_start, _heap_end - _heap_start ) }
22
26
//!
23
27
//! let mut xs = Vec::new();
24
28
//! xs.push(1);
37
41
//! _heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - _stack_size;
38
42
//! ```
39
43
40
- #![ allocator]
41
- #![ feature( allocator) ]
42
44
#![ feature( const_fn) ]
43
45
#![ no_std]
46
+ #![ feature( alloc, allocator_api) ]
44
47
45
48
extern crate cortex_m;
46
49
extern crate linked_list_allocator;
50
+ extern crate alloc;
47
51
48
- use core :: { cmp , ptr } ;
52
+ use alloc :: allocator :: { Alloc , Layout , AllocErr } ;
49
53
50
54
use linked_list_allocator:: Heap ;
51
55
use cortex_m:: interrupt:: Mutex ;
52
56
53
- /// A global UNINITIALIZED heap allocator
54
- ///
55
- /// You must initialize this heap using the
56
- /// [`init`](struct.Heap.html#method.init) method before using the allocator.
57
- static HEAP : Mutex < Heap > = Mutex :: new ( Heap :: empty ( ) ) ;
58
-
59
- /// Initializes the heap
60
- ///
61
- /// This function must be called BEFORE you run any code that makes use of the
62
- /// allocator.
63
- ///
64
- /// `start_addr` is the address where the heap will be located.
65
- ///
66
- /// `end_addr` points to the end of the heap.
67
- ///
68
- /// Note that:
69
- ///
70
- /// - The heap grows "upwards", towards larger addresses. Thus `end_addr` must
71
- /// be larger than `start_addr`
72
- ///
73
- /// - The size of the heap is `(end_addr as usize) - (start_addr as usize)`. The
74
- /// allocator won't use the byte at `end_addr`.
75
- ///
76
- /// # Unsafety
77
- ///
78
- /// Obey these or Bad Stuff will happen.
79
- ///
80
- /// - This function must be called exactly ONCE.
81
- /// - `end_addr` > `start_addr`
82
- pub unsafe fn init ( start_addr : * mut usize , end_addr : * mut usize ) {
83
- let start = start_addr as usize ;
84
- let end = end_addr as usize ;
85
- let size = end - start;
86
- HEAP . lock ( |heap| heap. init ( start, size) ) ;
57
+ pub struct CortexMHeap {
58
+ heap : Mutex < Heap > ,
87
59
}
88
60
89
- // Rust allocator interface
90
-
91
- #[ doc( hidden) ]
92
- #[ no_mangle]
93
- /// Rust allocation function (c.f. malloc)
94
- pub extern "C" fn __rust_allocate ( size : usize , align : usize ) -> * mut u8 {
95
- HEAP . lock ( |heap| {
96
- heap. allocate_first_fit ( size, align) . expect ( "out of memory" )
97
- } )
98
- }
61
+ impl CortexMHeap {
99
62
100
- # [ doc ( hidden ) ]
101
- # [ no_mangle ]
102
- pub extern fn __rust_allocate_zeroed ( size : usize , align : usize ) -> * mut u8 {
103
- let ptr = __rust_allocate ( size , align ) ;
104
- if !ptr . is_null ( ) {
105
- unsafe {
106
- ptr :: write_bytes ( ptr , 0 , size ) ;
63
+ /// Crate a new UNINITIALIZED heap allocator
64
+ ///
65
+ /// You must initialize this heap using the
66
+ /// [`init`](struct.CortexMHeap.html#method.init) method before using the allocator.
67
+ pub const fn empty ( ) -> CortexMHeap {
68
+ CortexMHeap {
69
+ heap : Mutex :: new ( Heap :: empty ( ) ) ,
107
70
}
108
71
}
109
- ptr
110
- }
111
-
112
- /// Rust de-allocation function (c.f. free)
113
- #[ doc( hidden) ]
114
- #[ no_mangle]
115
- pub extern "C" fn __rust_deallocate ( ptr : * mut u8 , size : usize , align : usize ) {
116
- HEAP . lock ( |heap| unsafe { heap. deallocate ( ptr, size, align) } ) ;
117
- }
118
72
119
- /// Rust re-allocation function (c.f. realloc)
120
- #[ doc( hidden) ]
121
- #[ no_mangle]
122
- pub extern "C" fn __rust_reallocate ( ptr : * mut u8 ,
123
- size : usize ,
124
- new_size : usize ,
125
- align : usize )
126
- -> * mut u8 {
127
-
128
- // from: https://github.com/rust-lang/rust/blob/
129
- // c66d2380a810c9a2b3dbb4f93a830b101ee49cc2/
130
- // src/liballoc_system/lib.rs#L98-L101
131
-
132
- let new_ptr = __rust_allocate ( new_size, align) ;
133
- unsafe { ptr:: copy ( ptr, new_ptr, cmp:: min ( size, new_size) ) } ;
134
- __rust_deallocate ( ptr, size, align) ;
135
- new_ptr
73
+ /// Initializes the heap
74
+ ///
75
+ /// This function must be called BEFORE you run any code that makes use of the
76
+ /// allocator.
77
+ ///
78
+ /// `start_addr` is the address where the heap will be located.
79
+ ///
80
+ /// `size` is the size of the heap in bytes.
81
+ ///
82
+ /// Note that:
83
+ ///
84
+ /// - The heap grows "upwards", towards larger addresses. Thus `end_addr` must
85
+ /// be larger than `start_addr`
86
+ ///
87
+ /// - The size of the heap is `(end_addr as usize) - (start_addr as usize)`. The
88
+ /// allocator won't use the byte at `end_addr`.
89
+ ///
90
+ /// # Unsafety
91
+ ///
92
+ /// Obey these or Bad Stuff will happen.
93
+ ///
94
+ /// - This function must be called exactly ONCE.
95
+ /// - `size > 0`
96
+ pub unsafe fn init ( & self , start_addr : usize , size : usize ) {
97
+ self . heap . lock ( |heap| heap. init ( start_addr, size) ) ;
98
+ }
136
99
}
137
100
138
- /// Rust re-allocation function which guarantees not to move the data
139
- /// somewhere else.
140
- #[ doc( hidden) ]
141
- #[ no_mangle]
142
- pub extern "C" fn __rust_reallocate_inplace ( _ptr : * mut u8 ,
143
- size : usize ,
144
- _new_size : usize ,
145
- _align : usize )
146
- -> usize {
147
- size
148
- }
101
+ unsafe impl < ' a > Alloc for & ' a CortexMHeap {
102
+ unsafe fn alloc ( & mut self , layout : Layout ) -> Result < * mut u8 , AllocErr > {
103
+ self . heap . lock ( |heap| {
104
+ heap. allocate_first_fit ( layout)
105
+ } )
106
+ }
149
107
150
- /// Some allocators (pool allocators generally) over-allocate. This checks how
151
- /// much space there is at a location. Our allocator doesn't over allocate so
152
- /// this just returns `size`
153
- #[ doc( hidden) ]
154
- #[ no_mangle]
155
- pub extern "C" fn __rust_usable_size ( size : usize , _align : usize ) -> usize {
156
- size
157
- }
108
+ unsafe fn dealloc ( & mut self , ptr : * mut u8 , layout : Layout ) {
109
+ self . heap . lock ( |heap| heap. deallocate ( ptr, layout) ) ;
110
+ }
111
+ }
0 commit comments