Skip to content

Commit 7ead468

Browse files
author
Jorge Aparicio
committed
initial commit
0 parents  commit 7ead468

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
target
2+
Cargo.lock

Cargo.toml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "alloc-cortex-m"
3+
version = "0.1.0"
4+
authors = ["Jorge Aparicio <[email protected]>"]
5+
6+
[dependencies]
7+
cortex-m = "0.1.5"
8+
9+
[dependencies.linked_list_allocator]
10+
branch = "init"
11+
git = "https://github.com/japaric/linked-list-allocator"

src/lib.rs

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//! A heap allocator for Cortex-M processors
2+
//!
3+
//! # Example
4+
//!
5+
//! ```
6+
//! // Plug in the allocator
7+
//! extern crate alloc_cortex_m;
8+
//! extern crate collections;
9+
//!
10+
//! use alloc_cortex_m::HEAP;
11+
//! use collections::Vec;
12+
//!
13+
//! #[no_mangle]
14+
//! pub fn main() -> ! {
15+
//! // Initialize the heap BEFORE you use the allocator
16+
//! unsafe { HEAP.init(0x2000_0000, 1024) }
17+
//!
18+
//! let mut xs = Vec::new();
19+
//! xs.push(1);
20+
//! // ...
21+
//! }
22+
//! ```
23+
24+
#![allocator]
25+
#![feature(allocator)]
26+
#![feature(const_fn)]
27+
#![no_std]
28+
29+
extern crate cortex_m;
30+
extern crate linked_list_allocator;
31+
32+
use core::{ptr, cmp};
33+
34+
use cortex_m::interrupt::Mutex;
35+
36+
/// A global UNINITIALIZED heap allocator
37+
///
38+
/// You must initialize this heap using the
39+
/// [`init`](struct.Heap.html#method.init) method before using the allocator.
40+
pub static HEAP: Mutex<Heap> = Mutex::new(Heap::empty());
41+
42+
/// A heap allocator
43+
// NOTE newtype to hide all the other Heap methods
44+
pub struct Heap {
45+
inner: linked_list_allocator::Heap,
46+
}
47+
48+
impl Heap {
49+
const fn empty() -> Self {
50+
Heap { inner: linked_list_allocator::Heap::empty() }
51+
}
52+
53+
/// Initializes the heap
54+
///
55+
/// This method must be called before you run any code that makes use of the
56+
/// allocator.
57+
///
58+
/// This method must be called exactly ONCE.
59+
///
60+
/// `heap_bottom` is the address where the heap will be located. Note that
61+
/// heap grows "upwards", towards larger addresses.
62+
///
63+
/// `heap_size` is the size of the heap in bytes
64+
pub unsafe fn init(&mut self, heap_bottom: usize, heap_size: usize) {
65+
self.inner.init(heap_bottom, heap_size);
66+
}
67+
}
68+
69+
// Rust allocator interface
70+
71+
#[doc(hidden)]
72+
#[no_mangle]
73+
/// Rust allocation function (c.f. malloc)
74+
pub extern "C" fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
75+
HEAP.lock(|heap| {
76+
heap.inner.allocate_first_fit(size, align).expect("out of memory")
77+
})
78+
}
79+
80+
/// Rust de-allocation function (c.f. free)
81+
#[doc(hidden)]
82+
#[no_mangle]
83+
pub extern "C" fn __rust_deallocate(ptr: *mut u8, size: usize, align: usize) {
84+
HEAP.lock(|heap| unsafe { heap.inner.deallocate(ptr, size, align) });
85+
}
86+
87+
/// Rust re-allocation function (c.f. realloc)
88+
#[doc(hidden)]
89+
#[no_mangle]
90+
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
91+
size: usize,
92+
new_size: usize,
93+
align: usize)
94+
-> *mut u8 {
95+
96+
// from: https://github.com/rust-lang/rust/blob/
97+
// c66d2380a810c9a2b3dbb4f93a830b101ee49cc2/
98+
// src/liballoc_system/lib.rs#L98-L101
99+
100+
let new_ptr = __rust_allocate(new_size, align);
101+
unsafe { ptr::copy(ptr, new_ptr, cmp::min(size, new_size)) };
102+
__rust_deallocate(ptr, size, align);
103+
new_ptr
104+
}
105+
106+
/// Rust re-allocation function which guarantees not to move the data
107+
/// somewhere else.
108+
#[doc(hidden)]
109+
#[no_mangle]
110+
pub extern "C" fn __rust_reallocate_inplace(_ptr: *mut u8,
111+
size: usize,
112+
_new_size: usize,
113+
_align: usize)
114+
-> usize {
115+
size
116+
}
117+
118+
/// Some allocators (pool allocators generally) over-allocate. This checks how
119+
/// much space there is at a location. Our allocator doesn't over allocate so
120+
/// this just returns `size`
121+
#[doc(hidden)]
122+
#[no_mangle]
123+
pub extern "C" fn __rust_usable_size(size: usize, _align: usize) -> usize {
124+
size
125+
}

0 commit comments

Comments
 (0)