Skip to content
Snippets Groups Projects

Hercules Box

Merged rarbore2 requested to merge hercules_box into main
4 files
+ 103
0
Compare changes
  • Side-by-side
  • Inline
Files
4
+ 91
0
use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
use std::marker::PhantomData;
use std::ptr::{copy_nonoverlapping, NonNull};
/*
* An in-memory collection object that can be used by functions compiled by the
* Hercules compiler.
*/
pub struct HerculesBox<'a> {
cpu_shared: Option<NonNull<u8>>,
cpu_exclusive: Option<NonNull<u8>>,
cpu_owned: Option<NonNull<u8>>,
size: usize,
_phantom: PhantomData<&'a u8>,
}
impl<'a> HerculesBox<'a> {
pub fn from_slice<T>(slice: &'a [T]) -> Self {
HerculesBox {
cpu_shared: Some(unsafe { NonNull::new_unchecked(slice.as_ptr() as *mut u8) }),
cpu_exclusive: None,
cpu_owned: None,
size: slice.len() * align_of::<T>(),
_phantom: PhantomData,
}
}
pub fn from_slice_mut<T>(slice: &'a mut [T]) -> Self {
HerculesBox {
cpu_shared: None,
cpu_exclusive: Some(unsafe { NonNull::new_unchecked(slice.as_mut_ptr() as *mut u8) }),
cpu_owned: None,
size: slice.len() * align_of::<T>(),
_phantom: PhantomData,
}
}
unsafe fn into_cpu(&mut self) -> NonNull<u8> {
self.cpu_shared
.or(self.cpu_exclusive)
.or(self.cpu_owned)
.unwrap()
}
unsafe fn into_cpu_mut(&mut self) -> NonNull<u8> {
if let Some(ptr) = self.cpu_exclusive.or(self.cpu_owned) {
ptr
} else {
let ptr =
NonNull::new(alloc(Layout::from_size_align_unchecked(self.size, 16))).unwrap();
copy_nonoverlapping(self.cpu_shared.unwrap().as_ptr(), ptr.as_ptr(), self.size);
self.cpu_owned = Some(ptr);
self.cpu_shared = None;
ptr
}
}
pub unsafe fn __zeros(size: usize) -> Self {
HerculesBox {
cpu_shared: None,
cpu_exclusive: None,
cpu_owned: Some(
NonNull::new(alloc_zeroed(Layout::from_size_align_unchecked(size, 16))).unwrap(),
),
size: size,
_phantom: PhantomData,
}
}
pub unsafe fn __cpu_ptr(&mut self) -> *mut u8 {
self.into_cpu().as_ptr()
}
pub unsafe fn __cpu_ptr_mut(&mut self) -> *mut u8 {
self.into_cpu_mut().as_ptr()
}
}
impl<'a> Drop for HerculesBox<'a> {
fn drop(&mut self) {
if let Some(ptr) = self.cpu_owned {
unsafe {
dealloc(
ptr.as_ptr(),
Layout::from_size_align_unchecked(self.size, 16),
)
}
}
}
}
Loading