extern crate libc;
use core::cmp;
use core::ptr;
use libc::{c_int, c_void, size_t};
#[cfg_attr(target_os = "android", link(name = "gcc"))]
#[cfg_attr(all(not(windows),
not(target_os = "android"),
not(target_env = "musl")),
link(name = "pthread"))]
extern "C" {
fn hoard_malloc(size: size_t) -> *mut c_void;
fn hoard_posix_memalign(ptr: *mut *mut c_void, size: size_t, align: size_t) -> c_int;
fn hoard_realloc(ptr: *mut c_void, size: size_t) -> *mut c_void;
fn hoard_free(ptr: *mut c_void);
}
#[cfg(all(any(target_arch = "x86",
target_arch = "arm",
target_arch = "mips",
target_arch = "mipsel",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "powerpc64le")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
hoard_malloc(size as libc::size_t) as *mut u8
} else {
let mut out = ptr::null_mut();
let ret = hoard_posix_memalign(&mut out, align as libc::size_t, size as libc::size_t);
if ret != 0 {
ptr::null_mut()
} else {
out as *mut u8
}
}
}
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
hoard_realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
} else {
let new_ptr = allocate(size, align);
ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
deallocate(ptr, old_size, align);
new_ptr
}
}
pub unsafe fn reallocate_inplace(_ptr: *mut u8,
old_size: usize,
_size: usize,
_align: usize)
-> usize {
old_size
}
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
hoard_free(ptr as *mut libc::c_void)
}
pub fn usable_size(size: usize, _align: usize) -> usize {
size
}