add impls for both alloc and esp-alloc

This commit is contained in:
Hailey Somerville 2023-09-14 18:07:00 +10:00
parent 445d048f23
commit 760e81ecf6
5 changed files with 116 additions and 16 deletions

23
Cargo.lock generated
View file

@ -88,6 +88,7 @@ version = "0.1.0"
dependencies = [
"bytemuck",
"derive_more",
"esp-alloc",
]
[[package]]
@ -297,6 +298,12 @@ dependencies = [
"windows",
]
[[package]]
name = "critical-section"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
[[package]]
name = "dasp_sample"
version = "0.11.0"
@ -322,6 +329,16 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "esp-alloc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83792eb7261a375bb838679fea2b45654b8f4a48da6bef10a96da5054aa81c7d"
dependencies = [
"critical-section",
"linked_list_allocator",
]
[[package]]
name = "getrandom"
version = "0.2.10"
@ -459,6 +476,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "linked_list_allocator"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
[[package]]
name = "lock_api"
version = "0.4.10"

View file

@ -5,7 +5,9 @@ edition = "2021"
[features]
alloc = ["bytemuck/extern_crate_alloc"]
esp_alloc = ["esp-alloc"]
[dependencies]
esp-alloc = { version = "0.3", optional = true }
bytemuck = { workspace = true, optional = true }
derive_more = { workspace = true }

View file

@ -0,0 +1,14 @@
extern crate alloc;
use derive_more::{Deref, DerefMut};
#[repr(transparent)]
#[derive(Deref, DerefMut)]
#[deref(forward)]
pub struct FixedBuffer<const N: usize>(alloc::boxed::Box<[u8]>);
impl<const N: usize> FixedBuffer<N> {
pub fn alloc_zeroed() -> Self {
FixedBuffer(bytemuck::allocation::zeroed_slice_box(N))
}
}

View file

@ -0,0 +1,71 @@
use core::alloc::{GlobalAlloc, Layout};
use core::ops::{Deref, DerefMut};
use core::ptr::null_mut;
use core::slice;
use core::sync::atomic::{AtomicPtr, Ordering};
use esp_alloc::EspHeap;
static HEAP: AtomicPtr<EspHeap> = AtomicPtr::new(null_mut());
pub unsafe fn set_heap(heap: &'static EspHeap) {
let result = HEAP.compare_exchange(
null_mut(),
heap as *const _ as *mut _,
Ordering::SeqCst,
Ordering::Relaxed,
);
if result.is_err() {
panic!("bark_alloc: attempted to call set_heap twice");
}
}
fn heap() -> &'static EspHeap {
let ptr = HEAP.load(Ordering::Relaxed);
if ptr == null_mut() {
panic!("bark_alloc: heap accessed before set! call set_heap first.")
}
unsafe { &*(ptr as *const _) }
}
#[repr(transparent)]
pub struct FixedBuffer<const N: usize>(*mut u8);
impl<const N: usize> FixedBuffer<N> {
const LAYOUT: Layout = unsafe {
// Layout::from_size_align is const but returns a Result,
// we can't const unwrap results on stable rust yet.
Layout::from_size_align_unchecked(N, 4)
};
pub fn alloc_zeroed() -> Self {
let ptr = unsafe { heap().alloc_zeroed(Self::LAYOUT) };
if ptr == null_mut() {
panic!("bark_alloc: allocation failed! requsted size: {N}");
}
FixedBuffer(ptr)
}
}
impl<const N: usize> Drop for FixedBuffer<N> {
fn drop(&mut self) {
unsafe { heap().dealloc(self.0, Self::LAYOUT); }
}
}
impl<const N: usize> Deref for FixedBuffer<N> {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.0, N) }
}
}
impl<const N: usize> DerefMut for FixedBuffer<N> {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.0, N) }
}
}

View file

@ -1,24 +1,14 @@
#![no_std]
#[cfg(not(feature = "alloc"))]
#[cfg(not(any(feature = "alloc", feature = "esp_alloc")))]
compile_error!("must enable alloc feature!");
#[cfg(feature = "alloc")]
mod impl_ {
extern crate alloc;
#[path = "alloc_box_impl.rs"]
mod impl_;
use derive_more::{Deref, DerefMut};
#[repr(transparent)]
#[derive(Deref, DerefMut)]
#[deref(forward)]
pub struct FixedBuffer<const N: usize>(alloc::boxed::Box<[u8]>);
impl<const N: usize> FixedBuffer<N> {
pub fn alloc_zeroed() -> Self {
FixedBuffer(bytemuck::allocation::zeroed_slice_box(N))
}
}
}
#[cfg(feature = "esp_alloc")]
#[path = "esp_alloc_impl.rs"]
mod impl_;
pub use impl_::*;