$ arm-none-eabi-size target/thumbv7m-none-eabi/release/app
text data bss dec hex filename
1900 104 12 2016 7e0 target/thumbv7m-none-eabi/release/app
$ # with the Box stuff removed from main
$ arm-none-eabi-size target/thumbv7m-none-eabi/release/app
text data bss dec hex filename
1436 0 0 1436 59c target/thumbv7m-none-eabi/release/app
-
-
Save japaric/b5e0a7450d968f6ca29c4d238d34a2d0 to your computer and use it in GitHub Desktop.
Using newlib's allocator as Rust's allocator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(allocator_api)] | |
#![no_std] | |
extern crate cty; | |
use core::heap::{Alloc, AllocErr, Layout}; | |
use core::{cmp, ptr}; | |
use cty::c_void; | |
// C heap allocator | |
pub struct Heap; | |
#[link(name = "c_nano")] | |
extern "C" { | |
fn free(ptr: *mut c_void); | |
fn malloc(size: usize) -> *mut c_void; | |
fn memalign(alignment: usize, size: usize) -> *mut c_void; | |
fn realloc(ptr: *mut c_void, size: usize) -> *mut c_void; | |
} | |
const MIN_ALIGN: usize = 8; | |
// FIXME C malloc/free are not thread / interrupt safe. These implementations need a Mutex | |
unsafe impl<'a> Alloc for &'a Heap { | |
#[inline] | |
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> { | |
let ptr = if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { | |
malloc(layout.size()) as *mut u8 | |
} else { | |
aligned_malloc(&layout) | |
}; | |
if !ptr.is_null() { | |
Ok(ptr) | |
} else { | |
Err(AllocErr::Exhausted { request: layout }) | |
} | |
} | |
#[inline] | |
unsafe fn dealloc(&mut self, ptr: *mut u8, _layout: Layout) { | |
free(ptr as *mut c_void) | |
} | |
#[inline] | |
unsafe fn realloc( | |
&mut self, | |
ptr: *mut u8, | |
old_layout: Layout, | |
new_layout: Layout, | |
) -> Result<*mut u8, AllocErr> { | |
if old_layout.align() != new_layout.align() { | |
return Err(AllocErr::Unsupported { | |
details: "cannot change alignment on `realloc`", | |
}); | |
} | |
if new_layout.align() <= MIN_ALIGN && new_layout.align() <= new_layout.size() { | |
let ptr = realloc(ptr as *mut c_void, new_layout.size()); | |
if !ptr.is_null() { | |
Ok(ptr as *mut u8) | |
} else { | |
Err(AllocErr::Exhausted { | |
request: new_layout, | |
}) | |
} | |
} else { | |
let res = self.alloc(new_layout.clone()); | |
if let Ok(new_ptr) = res { | |
let size = cmp::min(old_layout.size(), new_layout.size()); | |
ptr::copy_nonoverlapping(ptr, new_ptr, size); | |
self.dealloc(ptr, old_layout); | |
} | |
res | |
} | |
} | |
} | |
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { | |
memalign(layout.align(), layout.size()) as *mut u8 | |
} | |
// Required by malloc | |
// This implementation is tailored to cortex-m-rt | |
#[no_mangle] | |
pub unsafe extern "C" fn _sbrk(nbytes: isize) -> *mut c_void { | |
extern "C" { | |
static mut _sheap: u8; | |
static mut _eheap: u8; | |
} | |
static mut HEAP: *mut u8 = unsafe { &_sheap as *const u8 as *mut u8 }; | |
let eheap = &mut _eheap as *mut u8; | |
let base = HEAP; | |
let new = base.offset(nbytes); | |
if new < eheap { | |
HEAP = new; | |
base as *mut c_void | |
} else { | |
// OOM | |
0 as *mut c_void | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
// .. | |
#[global_allocator] | |
static HEAP: Heap = Heap; | |
#[inline(never)] | |
fn main() { | |
let x = Box::new(0); | |
unsafe { ptr::read_volatile(&*x) }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment