Skip to content

Commit

Permalink
C++ Don't use aligned_malloc because we can't rely on that in esp-idf
Browse files Browse the repository at this point in the history
Instead, try to do the alignment manually for over-aligned allocations
  • Loading branch information
ogoffart committed Jul 21, 2023
1 parent ef8ddaa commit 422c39d
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions api/cpp/lib.rs
Expand Up @@ -143,17 +143,32 @@ mod allocator {
use core::ffi::c_void;
extern "C" {
pub fn free(p: *mut c_void);
// This function is part of C11 & C++17
pub fn aligned_alloc(alignment: usize, size: usize) -> *mut c_void;
pub fn malloc(size: usize) -> *mut c_void;
}

struct CAlloc;
unsafe impl core::alloc::GlobalAlloc for CAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
aligned_alloc(layout.align(), layout.size()) as *mut u8
let align = layout.align();
if align <= core::mem::size_of::<usize>() {
malloc(layout.size()) as *mut u8
} else {
// Ideally we'd use alligned_alloc, but that function caused heap corruption with esp-idf
let ptr = malloc(layout.size() + align) as *mut u8;
let shift = align - (ptr as usize % align);
let ptr = ptr.add(shift);
core::ptr::write(ptr.sub(1), shift as u8);
ptr
}
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
free(ptr as *mut c_void);
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let align = layout.align();
if align <= core::mem::size_of::<usize>() {
free(ptr as *mut c_void);
} else {
let shift = core::ptr::read(ptr.sub(1)) as usize;
free(ptr.sub(shift) as *mut c_void);
}
}
}

Expand Down

0 comments on commit 422c39d

Please sign in to comment.