use crate::memory::CACHE_LINE_SIZE;
use std::alloc::Layout;
use std::ptr::NonNull;
pub struct CacheAlignedAllocator;
fn cache_aligned_array<T>(count: usize) -> Option<Layout> {
Layout::array::<T>(count)
.ok()?
.align_to(CACHE_LINE_SIZE)
.ok()
}
impl CacheAlignedAllocator {
pub fn allocate<T>(count: usize) -> Option<NonNull<T>> {
let layout = cache_aligned_array::<T>(count)?;
if layout.size() == 0 {
return None;
}
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) {
unsafe {
if let Some(layout) = cache_aligned_array::<T>(count) {
#[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);
}
}
}
}
}