use ::core::alloc::{GlobalAlloc, Layout};
use ::core::ffi::c_void;
#[global_allocator]
static ALLOCATOR: LvglAlloc = LvglAlloc;
#[cfg(all(LV_USE_STDLIB_MALLOC = "BUILTIN", not(feature = "ctor")))]
compile_error!(
"`lvgl-alloc` and `LV_USE_STDLIB_MALLOC = BUILTIN` without `ctor` gives instant segmentation fault"
);
pub struct LvglAlloc;
unsafe impl GlobalAlloc for LvglAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
unsafe {
const USIZE_BYTES: usize = (usize::BITS / u8::BITS) as usize;
let extra_bytes = USIZE_BYTES + (layout.align() - 1);
let raw = lightvgl_sys::lv_malloc(layout.size() + extra_bytes).cast::<u8>();
let raw_shifted = raw.add(USIZE_BYTES);
let offset = raw_shifted.align_offset(layout.align());
let aligned = raw_shifted.wrapping_add(offset);
*((aligned.cast::<usize>()).sub(1)) = offset + USIZE_BYTES;
aligned
}
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
unsafe {
let offset = *(ptr.cast::<usize>()).sub(1);
let raw = ptr.sub(offset);
lightvgl_sys::lv_free(raw.cast::<c_void>());
}
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
unsafe {
const USIZE_BYTES: usize = (usize::BITS / u8::BITS) as usize;
let extra_bytes = USIZE_BYTES + (layout.align() - 1);
let raw = lightvgl_sys::lv_calloc(layout.size() + extra_bytes, 1).cast::<u8>();
let raw_shifted = raw.add(USIZE_BYTES);
let offset = raw_shifted.align_offset(layout.align());
let aligned = raw_shifted.wrapping_add(offset);
*((aligned.cast::<usize>()).sub(1)) = offset + USIZE_BYTES;
aligned
}
}
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
unsafe {
let offset = *(ptr.cast::<usize>()).sub(1);
let old = ptr.sub(offset).cast::<c_void>();
const USIZE_BYTES: usize = (usize::BITS / u8::BITS) as usize;
let extra_bytes = USIZE_BYTES + (layout.align() - 1);
let raw = lightvgl_sys::lv_realloc(old, new_size + extra_bytes).cast::<u8>();
let raw_shifted = raw.add(USIZE_BYTES);
let offset = raw_shifted.align_offset(layout.align());
let aligned = raw_shifted.add(offset);
*((aligned.cast::<usize>()).sub(1)) = offset + USIZE_BYTES;
aligned
}
}
}