117 lines
2.9 KiB
Rust
117 lines
2.9 KiB
Rust
#![allow(unused_variables)]
|
|
|
|
use core::alloc::GlobalAlloc;
|
|
use core::ffi::{c_size_t, c_void};
|
|
|
|
use enumset::EnumSet;
|
|
use esp_alloc::EspHeap;
|
|
|
|
use crate::ffi::string::__xkbc_memcpy;
|
|
|
|
// Here we select the allocator to use for libxkbcommon.
|
|
static XKBC_ALLOCATOR: &EspHeap = &crate::PSRAM_ALLOCATOR;
|
|
|
|
// Implementation based on esp-alloc's `compat` feature.
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_malloc(size: c_size_t) -> *mut c_void {
|
|
unsafe { malloc_with_caps(size, EnumSet::empty()) as *mut _ }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_malloc(size: c_size_t) -> *mut c_void {
|
|
unsafe { __xkbc_malloc(size) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_calloc(number: c_size_t, size: c_size_t) -> *mut c_void {
|
|
let total_size = number * size;
|
|
unsafe {
|
|
let ptr = __xkbc_malloc(total_size) as *mut u8;
|
|
|
|
if !ptr.is_null() {
|
|
for i in 0..total_size as isize {
|
|
ptr.offset(i).write_volatile(0);
|
|
}
|
|
}
|
|
|
|
ptr as *mut _
|
|
}
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_calloc(number: c_size_t, size: c_size_t) -> *mut c_void {
|
|
unsafe { __xkbc_calloc(number, size) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_realloc(ptr: *mut c_void, new_size: c_size_t) -> *mut c_void {
|
|
unsafe { realloc_with_caps(ptr as *mut _, new_size, EnumSet::empty()) as *mut _ }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_realloc(ptr: *mut c_void, new_size: c_size_t) -> *mut c_void {
|
|
unsafe { __xkbc_realloc(ptr, new_size) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_free(ptr: *mut c_void) {
|
|
if ptr.is_null() {
|
|
return;
|
|
}
|
|
|
|
unsafe {
|
|
let ptr = ptr.offset(-4);
|
|
let total_size = *(ptr as *const usize);
|
|
|
|
XKBC_ALLOCATOR.dealloc(
|
|
ptr as *mut u8,
|
|
core::alloc::Layout::from_size_align_unchecked(total_size, 4),
|
|
)
|
|
}
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_free(ptr: *mut c_void) {
|
|
unsafe {
|
|
__xkbc_free(ptr);
|
|
}
|
|
}
|
|
|
|
unsafe fn malloc_with_caps(size: usize, caps: EnumSet<crate::MemoryCapability>) -> *mut u8 {
|
|
let total_size = size + 4;
|
|
|
|
unsafe {
|
|
let ptr = XKBC_ALLOCATOR.alloc_caps(
|
|
caps,
|
|
core::alloc::Layout::from_size_align_unchecked(total_size, 4),
|
|
);
|
|
|
|
if ptr.is_null() {
|
|
return ptr;
|
|
}
|
|
|
|
*(ptr as *mut usize) = total_size;
|
|
ptr.offset(4)
|
|
}
|
|
}
|
|
|
|
unsafe fn realloc_with_caps(
|
|
ptr: *mut u8,
|
|
new_size: usize,
|
|
caps: enumset::EnumSet<crate::MemoryCapability>,
|
|
) -> *mut u8 {
|
|
unsafe {
|
|
let p = malloc_with_caps(new_size, caps);
|
|
if !p.is_null() && !ptr.is_null() {
|
|
let len = usize::min(
|
|
(ptr as *const u32).sub(1).read_volatile() as usize,
|
|
new_size,
|
|
);
|
|
__xkbc_memcpy(p as *mut _, ptr as *const _, len);
|
|
__xkbc_free(ptr as *mut _);
|
|
}
|
|
p
|
|
}
|
|
}
|