Skip to content
This repository has been archived by the owner on Apr 16, 2024. It is now read-only.

Commit

Permalink
Add support for nightly allocator_api-feature
Browse files Browse the repository at this point in the history
  • Loading branch information
seijikun committed Mar 2, 2024
1 parent 0de0725 commit 506b0e8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ categories = [
"no-std",
]

[features]
nightly = []

[package.metadata.docs.rs]
default-target = "riscv32imc-unknown-none-elf"

Expand Down
65 changes: 65 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,49 @@
//!
//! **NOTE:** using this as your global allocator requires using Rust 1.68 or
//! greater, or the `nightly` release channel.
//!
//! # Using this as your Global Allocator
//! To use EspHeap as your global allocator, you need at least Rust 1.68 or nightly.
//!
//! ```rust
//! #[global_allocator]
//! static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
//!
//! fn init_heap() {
//! const HEAP_SIZE: usize = 32 * 1024;
//! static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
//!
//! unsafe {
//! ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
//! }
//! }
//! ```
//!
//! # Using this with the nightly `allocator_api`-feature
//! Sometimes you want to have single allocations in PSRAM, instead of an esp's
//! DRAM. For that, it's convenient to use the nightly `allocator_api`-feature, which allows
//! you to specify an allocator for single allocations.
//!
//! **NOTE:** To use this, you have to enable the create's `nightly` feature flag.
//!
//! Create and initialize an allocator to use in single allocations:
//! ```rust
//! static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
//!
//! fn init_psram_heap() {
//! unsafe {
//! PSRAM_ALLOCATOR.init(psram::psram_vaddr_start() as *mut u8, psram::PSRAM_BYTES);
//! }
//! }
//! ```
//!
//! And then use it in an allocation:
//! ```rust
//! let large_buffer: Vec<u8, _> = Vec::with_capacity_in(1048576, &PSRAM_ALLOCATOR);
//! ```

#![no_std]
#![cfg_attr(feature = "nightly", feature(allocator_api))]

pub mod macros;

Expand All @@ -14,6 +55,9 @@ use core::{
ptr::{self, NonNull},
};

#[ cfg( feature = "nightly" ) ]
use core::alloc::{AllocError, Allocator};

use critical_section::Mutex;
use linked_list_allocator::Heap;

Expand Down Expand Up @@ -92,3 +136,24 @@ unsafe impl GlobalAlloc for EspHeap {
});
}
}


#[ cfg( feature = "nightly" ) ]
unsafe impl Allocator for EspHeap {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
critical_section::with(|cs| {
let raw_ptr = self.heap
.borrow(cs)
.borrow_mut()
.allocate_first_fit(layout)
.map_err(|_| AllocError)?
.as_ptr();
let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
})
}

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
self.dealloc(ptr.as_ptr(), layout);
}
}

0 comments on commit 506b0e8

Please sign in to comment.