use crate::buffer::ffi;
use crate::buffer::{Header, Slot};
use std::ptr;
pub struct Pinned {
pub header: *mut Header,
pub slots: *mut Slot,
pub n_slots: usize,
}
unsafe impl Send for Pinned {}
unsafe impl Sync for Pinned {}
impl Pinned {
pub fn new(n_slots: usize) -> Result<Self, String> {
if !n_slots.is_power_of_two() {
return Err("n_slots must be a power of two".to_string());
}
let device_id = unsafe { ffi::cuda_init_device(0) };
if device_id < 0 {
return Err("Failed to initialize CUDA device".to_string());
}
let mut header_ptr: *mut Header = ptr::null_mut();
let mut slots_ptr: *mut Slot = ptr::null_mut();
println!(
"[Buffer] Allocating unified buffer with {} slots...",
n_slots
);
let result = unsafe {
ffi::init_unified_buffer(
&mut slots_ptr,
&mut header_ptr,
n_slots as std::os::raw::c_int,
)
};
if result != 0 || header_ptr.is_null() || slots_ptr.is_null() {
return Err("CUDA FFI call to init_unified_buffer failed".to_string());
}
println!("[Buffer] Unified buffer allocated successfully.");
Ok(Self {
header: header_ptr,
slots: slots_ptr,
n_slots,
})
}
#[inline]
pub fn as_header(&self) -> *mut Header {
self.header
}
#[inline]
pub fn header(&self) -> *mut Header {
self.header
}
#[inline]
pub fn as_slots(&self) -> *mut Slot {
self.slots
}
#[inline]
pub fn slots_ptr(&self) -> *mut Slot {
self.slots
}
#[inline]
pub fn slot_count(&self) -> usize {
self.n_slots
}
}
impl Drop for Pinned {
fn drop(&mut self) {
println!("[Buffer] Cleaning up unified CUDA buffer...");
unsafe {
ffi::cleanup_unified_buffer(self.slots, self.header);
}
}
}