use std::alloc::{alloc, dealloc, Layout};
use std::ptr::NonNull;
use std::fmt;
#[derive(Debug)]
#[non_exhaustive]
pub enum CudaRegistrationError {
AllocationFailed { size: usize, alignment: usize },
}
impl fmt::Display for CudaRegistrationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AllocationFailed { size, alignment } => {
write!(f, "failed to allocate PageLockedSegment of size {} requiring alignment {}", size, alignment)
}
}
}
}
impl std::error::Error for CudaRegistrationError {}
pub struct PageLockedSegment {
host_ptr: NonNull<u8>,
layout: Layout,
}
impl PageLockedSegment {
pub fn new(capacity: usize) -> Result<Self, CudaRegistrationError> {
let align = 4096; let layout = Layout::from_size_align(capacity, align).map_err(|_| {
CudaRegistrationError::AllocationFailed { size: capacity, alignment: align }
})?;
let ptr = unsafe { alloc(layout) };
let host_ptr = NonNull::new(ptr).ok_or(CudaRegistrationError::AllocationFailed {
size: capacity,
alignment: align
})?;
Ok(Self { host_ptr, layout })
}
pub fn as_ptr(&self) -> *mut u8 {
self.host_ptr.as_ptr()
}
}
impl Drop for PageLockedSegment {
fn drop(&mut self) {
unsafe {
dealloc(self.host_ptr.as_ptr(), self.layout);
}
tracing::info!("Cudagrep: Mathematically enforced Page-Locked memory deregulation via Drop intercept safely executed.");
}
}