use std::{
alloc::Layout,
ptr::{self, NonNull},
};
use serde::{Deserialize, Serialize};
use crate::{
mem::{CopyDirection, CopyError, DeviceMemory},
AllocError, Allocator,
};
use super::{Backend, GlobalBackend};
pub const GLOBAL_CPU_BACKEND: CpuBackend = CpuBackend;
#[derive(
Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct CpuBackend;
impl GlobalBackend for CpuBackend {
fn global() -> &'static Self {
&GLOBAL_CPU_BACKEND
}
}
unsafe impl Allocator for CpuBackend {
#[inline]
unsafe fn allocate(&self, layout: Layout) -> Result<ptr::NonNull<[u8]>, AllocError> {
let ptr = std::alloc::alloc(layout);
Ok(NonNull::slice_from_raw_parts(NonNull::new_unchecked(ptr), layout.size()))
}
#[inline]
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
std::alloc::dealloc(ptr.as_ptr(), layout);
}
}
impl DeviceMemory for CpuBackend {
#[inline]
unsafe fn copy_nonoverlapping(
&self,
src: *const u8,
dst: *mut u8,
size: usize,
_direction: CopyDirection,
) -> Result<(), CopyError> {
src.copy_to_nonoverlapping(dst, size);
Ok(())
}
#[inline]
unsafe fn write_bytes(&self, dst: *mut u8, value: u8, size: usize) -> Result<(), CopyError> {
dst.write_bytes(value, size);
Ok(())
}
}
unsafe impl Backend for CpuBackend {}