Skip to content

Commit

Permalink
Merge #56
Browse files Browse the repository at this point in the history
56: Use critical-section for heap locking, rename to `embedded-alloc`. r=adamgreig a=Dirbaio

This uses `critical_section::with` instead of `cortex_m::interrupt::free` to acquire a critical section. This allows customizing the critical section implementation, to make it sound for multicore chips for example.

This is a breaking change, so it'll require a 0.5 release.

Interestingly this makes the crate not cortex-m specific anymore. Perhaps it could be renamed to something more general?

TODO
- [x] Wait for cortex-m 0.7.6 release rust-embedded/cortex-m#449

Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
  • Loading branch information
bors[bot] and Dirbaio authored Dec 8, 2022
2 parents e805a4a + a807592 commit 89cb8d5
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 53 deletions.
39 changes: 25 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [v0.5.0] - 2022-12-06

### Changed

- Renamed crate from `alloc-cortex-m` to `embedded-alloc`.
- Renamed `CortexMHeap` to `Heap`.
- Use `critical-section` to lock the heap, instead of `cortex_m::interrupt::free()`.
This allows using this crate on non-Cortex-M systems, or on
Cortex-M systems that require a custom critical section implementation.

## [v0.4.3] - 2022-11-03

### Changed
Expand Down Expand Up @@ -96,17 +106,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Initial version of the allocator

[Unreleased]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.4.3...HEAD
[v0.4.3]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.4.2...v0.4.3
[v0.4.2]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.4.1...v0.4.2
[v0.4.1]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.4.0...v0.4.1
[v0.4.0]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.5...v0.4.0
[v0.3.5]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.4...v0.3.5
[v0.3.4]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.3...v0.3.4
[v0.3.3]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.2...v0.3.3
[v0.3.2]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.1...v0.3.2
[v0.3.1]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.3.0...v0.3.1
[v0.3.0]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.2.2...v0.3.0
[v0.2.2]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.2.1...v0.2.2
[v0.2.1]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.2.0...v0.2.1
[v0.2.0]: https://github.com/rust-embedded/alloc-cortex-m/compare/v0.1.0...v0.2.0
[Unreleased]: https://github.com/rust-embedded/embedded-alloc/compare/v0.5.0...HEAD
[v0.5.0]: https://github.com/rust-embedded/embedded-alloc/compare/v0.4.3...v0.5.0
[v0.4.3]: https://github.com/rust-embedded/embedded-alloc/compare/v0.4.2...v0.4.3
[v0.4.2]: https://github.com/rust-embedded/embedded-alloc/compare/v0.4.1...v0.4.2
[v0.4.1]: https://github.com/rust-embedded/embedded-alloc/compare/v0.4.0...v0.4.1
[v0.4.0]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.5...v0.4.0
[v0.3.5]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.4...v0.3.5
[v0.3.4]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.3...v0.3.4
[v0.3.3]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.2...v0.3.3
[v0.3.2]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.1...v0.3.2
[v0.3.1]: https://github.com/rust-embedded/embedded-alloc/compare/v0.3.0...v0.3.1
[v0.3.0]: https://github.com/rust-embedded/embedded-alloc/compare/v0.2.2...v0.3.0
[v0.2.2]: https://github.com/rust-embedded/embedded-alloc/compare/v0.2.1...v0.2.2
[v0.2.1]: https://github.com/rust-embedded/embedded-alloc/compare/v0.2.0...v0.2.1
[v0.2.0]: https://github.com/rust-embedded/embedded-alloc/compare/v0.1.0...v0.2.0
17 changes: 10 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@ authors = [
"Sébastien Béchet <sebastien.bechet@osinix.com>",
]

description = "A heap allocator for Cortex-M processors"
repository = "https://github.com/rust-embedded/alloc-cortex-m"
documentation = "https://docs.rs/alloc-cortex-m"
description = "A heap allocator for embedded systems"
repository = "https://github.com/rust-embedded/embedded-alloc"
documentation = "https://docs.rs/embedded-alloc"
readme = "README.md"
edition = "2018"

keywords = [
"allocator",
"embedded",
"arm",
"riscv",
"cortex-m",
]
license = "MIT OR Apache-2.0"
name = "alloc-cortex-m"
version = "0.4.3"
name = "embedded-alloc"
version = "0.5.0"

[dependencies]
cortex-m = "0.7.2"
critical-section = "1.0"

[dependencies.linked_list_allocator]
default-features = false
version = "0.10.4"
features = ["const_mut_refs"]

[dev-dependencies]
cortex-m-rt = "0.6.12"
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
[![crates.io](https://img.shields.io/crates/d/alloc-cortex-m.svg)](https://crates.io/crates/alloc-cortex-m)
[![crates.io](https://img.shields.io/crates/v/alloc-cortex-m.svg)](https://crates.io/crates/alloc-cortex-m)
[![crates.io](https://img.shields.io/crates/d/embedded-alloc.svg)](https://crates.io/crates/embedded-alloc)
[![crates.io](https://img.shields.io/crates/v/embedded-alloc.svg)](https://crates.io/crates/embedded-alloc)

# `alloc-cortex-m`
# `embedded-alloc`

> A heap allocator for Cortex-M processors
> A heap allocator for embedded systems.
Note that using this as your global allocator requires nightly Rust.

This project is developed and maintained by the [Cortex-M team][team].

## [Documentation](https://docs.rs/alloc-cortex-m)
## Example

For a usage example, see `examples/global_alloc.rs`.

## [Documentation](https://docs.rs/embedded-alloc)

## [Change log](CHANGELOG.md)

Expand Down
8 changes: 4 additions & 4 deletions examples/global_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
extern crate alloc;

use alloc::vec::Vec;
use alloc_cortex_m::CortexMHeap;
use core::alloc::Layout;
use core::panic::PanicInfo;
use cortex_m_rt::entry;
use embedded_alloc::Heap;

#[global_allocator]
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
static HEAP: Heap = Heap::empty();

#[entry]
fn main() -> ! {
// Initialize the allocator BEFORE you use it
{
use core::mem::MaybeUninit;
const HEAP_SIZE: usize = 1024;
static mut HEAP: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
unsafe { ALLOCATOR.init(HEAP.as_ptr() as usize, HEAP_SIZE) }
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
}

let mut xs = Vec::new();
Expand Down
39 changes: 16 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
//! A heap allocator for Cortex-M processors.
//!
//! Note that using this as your global allocator requires nightly Rust.
//!
//! # Example
//!
//! For a usage example, see `examples/global_alloc.rs`.

#![doc = include_str!("../README.md")]
#![no_std]

use core::alloc::{GlobalAlloc, Layout};
use core::cell::RefCell;
use core::ptr::{self, NonNull};

use cortex_m::interrupt::Mutex;
use linked_list_allocator::Heap;
use critical_section::Mutex;
use linked_list_allocator::Heap as LLHeap;

pub struct CortexMHeap {
heap: Mutex<RefCell<Heap>>,
pub struct Heap {
heap: Mutex<RefCell<LLHeap>>,
}

impl CortexMHeap {
impl Heap {
/// Crate a new UNINITIALIZED heap allocator
///
/// You must initialize this heap using the
/// [`init`](struct.CortexMHeap.html#method.init) method before using the allocator.
pub const fn empty() -> CortexMHeap {
CortexMHeap {
heap: Mutex::new(RefCell::new(Heap::empty())),
/// [`init`](Self::init) method before using the allocator.
pub const fn empty() -> Heap {
Heap {
heap: Mutex::new(RefCell::new(LLHeap::empty())),
}
}

Expand Down Expand Up @@ -54,7 +47,7 @@ impl CortexMHeap {
/// - This function must be called exactly ONCE.
/// - `size > 0`
pub unsafe fn init(&self, start_addr: usize, size: usize) {
cortex_m::interrupt::free(|cs| {
critical_section::with(|cs| {
self.heap
.borrow(cs)
.borrow_mut()
Expand All @@ -64,18 +57,18 @@ impl CortexMHeap {

/// Returns an estimate of the amount of bytes in use.
pub fn used(&self) -> usize {
cortex_m::interrupt::free(|cs| self.heap.borrow(cs).borrow_mut().used())
critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().used())
}

/// Returns an estimate of the amount of bytes available.
pub fn free(&self) -> usize {
cortex_m::interrupt::free(|cs| self.heap.borrow(cs).borrow_mut().free())
critical_section::with(|cs| self.heap.borrow(cs).borrow_mut().free())
}
}

unsafe impl GlobalAlloc for CortexMHeap {
unsafe impl GlobalAlloc for Heap {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
cortex_m::interrupt::free(|cs| {
critical_section::with(|cs| {
self.heap
.borrow(cs)
.borrow_mut()
Expand All @@ -86,7 +79,7 @@ unsafe impl GlobalAlloc for CortexMHeap {
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
cortex_m::interrupt::free(|cs| {
critical_section::with(|cs| {
self.heap
.borrow(cs)
.borrow_mut()
Expand Down

0 comments on commit 89cb8d5

Please sign in to comment.