Skip to content

Commit ae3d831

Browse files
authored
Merge pull request rust-embedded#7 from f-bro/new-alloc-api
Update alloc API to latest nightly
2 parents b11b99b + b30462a commit ae3d831

File tree

2 files changed

+55
-101
lines changed

2 files changed

+55
-101
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ version = "0.2.2"
99

1010
[dependencies]
1111
cortex-m = "0.1.5"
12-
linked_list_allocator = "0.2.3"
12+
linked_list_allocator = {git = "https://github.com/phil-opp/linked-list-allocator.git"}

src/lib.rs

+54-100
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
//! extern crate collections;
99
//!
1010
//! use collections::Vec;
11+
//! use alloc_cortex_m::CortexMHeap;
12+
//!
13+
//! #[global_allocator]
14+
//! static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
1115
//!
1216
//! // These symbols come from a linker script
1317
//! extern "C" {
@@ -18,7 +22,7 @@
1822
//! #[no_mangle]
1923
//! pub fn main() -> ! {
2024
//! // 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) }
2226
//!
2327
//! let mut xs = Vec::new();
2428
//! xs.push(1);
@@ -37,121 +41,71 @@
3741
//! _heap_end = ORIGIN(SRAM) + LENGTH(SRAM) - _stack_size;
3842
//! ```
3943
40-
#![allocator]
41-
#![feature(allocator)]
4244
#![feature(const_fn)]
4345
#![no_std]
46+
#![feature(alloc, allocator_api)]
4447

4548
extern crate cortex_m;
4649
extern crate linked_list_allocator;
50+
extern crate alloc;
4751

48-
use core::{cmp, ptr};
52+
use alloc::allocator::{Alloc, Layout, AllocErr};
4953

5054
use linked_list_allocator::Heap;
5155
use cortex_m::interrupt::Mutex;
5256

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>,
8759
}
8860

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 {
9962

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()),
10770
}
10871
}
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-
}
11872

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+
}
13699
}
137100

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+
}
149107

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

Comments
 (0)