use core::ffi::c_void;
use crate::Alignment;
pub mod z;
#[derive(Clone, Copy, Default)]
pub struct CAllocator;
pub static C_ALLOCATOR: CAllocator = CAllocator;
impl CAllocator {
#[inline]
pub fn raw_alloc(&self, len: usize, alignment: Alignment, _ret_addr: usize) -> Option<*mut u8> {
let align = alignment.to_byte_units();
let ptr = unsafe {
if align <= crate::MAX_ALIGN_T {
libc::malloc(len)
} else {
#[cfg(windows)]
{
libc::aligned_malloc(len, align)
}
#[cfg(not(windows))]
{
libc::aligned_alloc(align, len)
}
}
};
if ptr.is_null() {
None
} else {
Some(ptr.cast())
}
}
#[inline]
pub fn raw_resize(
&self,
buf: &mut [u8],
_alignment: Alignment,
new_len: usize,
_ret_addr: usize,
) -> bool {
if new_len <= buf.len() {
return true;
}
#[cfg(target_os = "macos")]
{
let usable = unsafe { libc::malloc_size(buf.as_ptr().cast()) };
return new_len <= usable;
}
#[cfg(any(target_os = "linux", target_os = "android"))]
{
let usable = unsafe { libc::malloc_usable_size(buf.as_mut_ptr().cast()) };
return new_len <= usable;
}
#[cfg(windows)]
{
unsafe extern "C" {
fn _msize(p: *mut c_void) -> usize;
fn _aligned_msize(p: *mut c_void, align: usize, offset: usize) -> usize;
}
let usable = unsafe {
if _alignment.to_byte_units() > crate::MAX_ALIGN_T {
_aligned_msize(buf.as_mut_ptr().cast(), _alignment.to_byte_units(), 0)
} else {
_msize(buf.as_mut_ptr().cast())
}
};
return new_len <= usable;
}
#[cfg(not(any(
target_os = "macos",
target_os = "linux",
target_os = "android",
windows
)))]
{
false
}
}
#[inline]
pub fn raw_free(&self, buf: &mut [u8], alignment: Alignment, _ret_addr: usize) {
#[cfg(windows)]
if alignment.to_byte_units() > crate::MAX_ALIGN_T {
unsafe { libc::aligned_free(buf.as_mut_ptr().cast()) };
return;
}
#[cfg(not(windows))]
let _ = alignment;
unsafe { libc::free(buf.as_mut_ptr().cast()) }
}
}
impl crate::Allocator for CAllocator {}
pub use z::ALLOCATOR as z_allocator;
pub unsafe fn free_without_size(ptr: *mut c_void) {
unsafe { libc::free(ptr) }
}