#![allow(unused)]
unsafe extern "C" {
pub fn malloc(size: usize) -> *mut u8;
pub fn malloc_internal(size: usize) -> *mut u8;
pub fn free(ptr: *mut u8);
pub fn free_internal(ptr: *mut u8);
pub fn realloc_internal(ptr: *mut u8, size: usize) -> *mut u8;
pub fn calloc(number: u32, size: usize) -> *mut u8;
pub fn calloc_internal(number: u32, size: usize) -> *mut u8;
pub fn get_free_internal_heap_size() -> usize;
}
#[cfg(not(feature = "esp-alloc"))]
mod esp_alloc {
use core::{alloc::Layout, ptr::NonNull};
use allocator_api2::alloc::{AllocError, Allocator};
pub struct InternalMemory;
unsafe impl Allocator for InternalMemory {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
let ptr = if layout.align() <= 4 {
unsafe { super::malloc_internal(layout.size()) }
} else {
let extra = layout.align().max(4);
let allocation = unsafe { super::malloc_internal(layout.size() + extra) };
if allocation.is_null() {
return Err(AllocError);
}
let ptr = allocation.wrapping_add(4);
let align_offset = ptr.align_offset(layout.align());
let data_ptr = ptr.wrapping_add(align_offset);
let prefix_ptr = data_ptr.wrapping_sub(4);
unsafe { prefix_ptr.cast::<usize>().write(align_offset) };
data_ptr
};
let ptr = NonNull::new(ptr).ok_or(AllocError)?;
Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
}
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
if layout.align() <= 4 {
unsafe { super::free_internal(ptr.as_ptr()) };
} else {
let prefix_ptr = ptr.as_ptr().wrapping_sub(4);
let prefix_bytes = unsafe { prefix_ptr.cast::<usize>().read() };
unsafe { super::free_internal(prefix_ptr.wrapping_sub(prefix_bytes)) };
}
}
}
}
pub(crate) use esp_alloc::InternalMemory;