use crate::memory::CACHE_LINE_SIZE;
use std::alloc::Layout;
use std::mem::{align_of, size_of};
use std::ptr::NonNull;
pub struct CacheAlignedAllocator;
impl CacheAlignedAllocator {
pub fn allocate<T>(count: usize) -> Option<NonNull<T>> {
let size = size_of::<T>() * count;
let align = align_of::<T>().max(CACHE_LINE_SIZE);
let layout = Layout::from_size_align(size, align).ok()?;
unsafe {
#[cfg(feature = "mnemosyne")]
{
use core::alloc::GlobalAlloc;
let ptr = mnemosyne::Mnemosyne.alloc(layout);
NonNull::new(ptr.cast::<T>())
}
#[cfg(not(feature = "mnemosyne"))]
{
let ptr = std::alloc::alloc(layout);
NonNull::new(ptr.cast::<T>())
}
}
}
pub unsafe fn deallocate<T>(ptr: NonNull<T>, count: usize) {
let size = size_of::<T>() * count;
let align = align_of::<T>().max(CACHE_LINE_SIZE);
if let Ok(layout) = Layout::from_size_align(size, align) {
#[cfg(feature = "mnemosyne")]
{
use core::alloc::GlobalAlloc;
mnemosyne::Mnemosyne.dealloc(ptr.as_ptr().cast::<u8>(), layout);
}
#[cfg(not(feature = "mnemosyne"))]
{
std::alloc::dealloc(ptr.as_ptr().cast::<u8>(), layout);
}
}
}
}