use core::ffi::c_void;
use core::sync::atomic::Ordering;
use super::registry::CUDA_HOST_PINNED_ALLOCATIONS;
use super::{CudaAllocOps, CudaAllocationRegistry, loader};
pub struct CudaHostPinnedBackend;
impl CudaAllocOps for CudaHostPinnedBackend {
#[inline]
fn registry() -> &'static CudaAllocationRegistry {
&CUDA_HOST_PINNED_ALLOCATIONS
}
#[inline]
fn alloc_sym() -> *mut c_void {
loader::CU_MEM_HOST_ALLOC.load(Ordering::Acquire)
}
#[inline]
fn free_sym() -> *mut c_void {
loader::CU_MEM_FREE_HOST.load(Ordering::Acquire)
}
#[inline]
unsafe fn raw_alloc(alloc_sym: *mut c_void, size: usize) -> *mut u8 {
type CuMemHostAllocFn =
unsafe extern "system" fn(*mut *mut c_void, usize, u32) -> core::ffi::c_int;
let cu_mem_host_alloc: CuMemHostAllocFn = unsafe { core::mem::transmute(alloc_sym) };
let mut host_ptr: *mut c_void = core::ptr::null_mut();
let res = unsafe { cu_mem_host_alloc(core::ptr::addr_of_mut!(host_ptr), size, 0x02) };
if res == 0 && !host_ptr.is_null() {
host_ptr as *mut u8
} else {
core::ptr::null_mut()
}
}
#[inline]
unsafe fn raw_free(free_sym: *mut c_void, ptr: *mut u8) -> core::ffi::c_int {
type CuMemFreeHostFn = unsafe extern "system" fn(*mut c_void) -> core::ffi::c_int;
let cu_mem_free_host: CuMemFreeHostFn = unsafe { core::mem::transmute(free_sym) };
unsafe { cu_mem_free_host(ptr as *mut c_void) }
}
}
impl_cuda_memory_backend!(CudaHostPinnedBackend);