#![allow(deprecated)]
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use std::marker::PhantomData;
use std::sync::Arc;
use crate::core::global::GlobalState;
use crate::core::tls;
#[deprecated(
since = "0.11.1",
note = "framealloc is deprecated. Use `memkit::MkFrameBox` instead (available in memkit 0.12+)"
)]
pub struct FrameBox<'a, T> {
ptr: NonNull<T>,
_marker: PhantomData<&'a T>,
}
impl<'a, T> FrameBox<'a, T> {
pub(crate) unsafe fn from_raw(ptr: *mut T) -> Option<Self> {
NonNull::new(ptr).map(|ptr| Self {
ptr,
_marker: PhantomData,
})
}
pub fn as_ptr(&self) -> *const T {
self.ptr.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.ptr.as_ptr()
}
pub fn into_raw(self) -> *mut T {
let ptr = self.ptr.as_ptr();
std::mem::forget(self);
ptr
}
}
impl<'a, T> Deref for FrameBox<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<'a, T> DerefMut for FrameBox<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut() }
}
}
#[deprecated(
since = "0.11.1",
note = "framealloc is deprecated. Use `memkit::MkPoolBox` instead (available in memkit 0.12+)"
)]
pub struct PoolBox<T> {
ptr: NonNull<T>,
global: Arc<GlobalState>,
}
impl<T> PoolBox<T> {
pub(crate) unsafe fn from_raw(ptr: *mut T, global: Arc<GlobalState>) -> Option<Self> {
NonNull::new(ptr).map(|ptr| Self { ptr, global })
}
pub fn as_ptr(&self) -> *const T {
self.ptr.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.ptr.as_ptr()
}
pub fn into_raw(self) -> *mut T {
let ptr = self.ptr.as_ptr();
std::mem::forget(self);
ptr
}
}
impl<T> Deref for PoolBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<T> DerefMut for PoolBox<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut() }
}
}
impl<T> Drop for PoolBox<T> {
fn drop(&mut self) {
tls::with_tls(|tls| {
tls.pool_free(self.ptr.as_ptr(), &self.global);
});
}
}
unsafe impl<T: Send> Send for PoolBox<T> {}
unsafe impl<T: Sync> Sync for PoolBox<T> {}
#[deprecated(
since = "0.11.1",
note = "framealloc is deprecated. Use `memkit::MkHeapBox` instead (available in memkit 0.12+)"
)]
pub struct HeapBox<T> {
ptr: NonNull<T>,
global: Arc<GlobalState>,
}
impl<T> HeapBox<T> {
pub(crate) unsafe fn from_raw(ptr: *mut T, global: Arc<GlobalState>) -> Option<Self> {
NonNull::new(ptr).map(|ptr| Self { ptr, global })
}
pub fn as_ptr(&self) -> *const T {
self.ptr.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.ptr.as_ptr()
}
pub fn into_raw(self) -> *mut T {
let ptr = self.ptr.as_ptr();
std::mem::forget(self);
ptr
}
}
impl<T> Deref for HeapBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.as_ref() }
}
}
impl<T> DerefMut for HeapBox<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.as_mut() }
}
}
impl<T> Drop for HeapBox<T> {
fn drop(&mut self) {
unsafe {
std::ptr::drop_in_place(self.ptr.as_ptr());
self.global.heap_free(self.ptr.as_ptr());
}
}
}
unsafe impl<T: Send> Send for HeapBox<T> {}
unsafe impl<T: Sync> Sync for HeapBox<T> {}
#[deprecated(
since = "0.11.1",
note = "framealloc is deprecated. Use `memkit::MkFrameSlice` instead (available in memkit 0.12+)"
)]
pub struct FrameSlice<'a, T> {
ptr: NonNull<T>,
len: usize,
_marker: PhantomData<&'a [T]>,
}
impl<'a, T> FrameSlice<'a, T> {
pub(crate) unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Option<Self> {
NonNull::new(ptr).map(|ptr| Self {
ptr,
len,
_marker: PhantomData,
})
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn as_ptr(&self) -> *const T {
self.ptr.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.ptr.as_ptr()
}
}
impl<'a, T> Deref for FrameSlice<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
}
}
impl<'a, T> DerefMut for FrameSlice<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
}
}
#[cfg(test)]
mod tests {
use crate::SmartAlloc;
#[test]
fn test_frame_box() {
let alloc = SmartAlloc::with_defaults();
alloc.begin_frame();
let boxed = alloc.frame_box(42u64).unwrap();
assert_eq!(*boxed, 42);
alloc.end_frame();
}
#[test]
fn test_pool_box() {
let alloc = SmartAlloc::with_defaults();
{
let boxed = alloc.pool_box(123u64).unwrap();
assert_eq!(*boxed, 123);
}
let boxed2 = alloc.pool_box(456u64).unwrap();
assert_eq!(*boxed2, 456);
}
#[test]
fn test_heap_box() {
let alloc = SmartAlloc::with_defaults();
{
let boxed = alloc.heap_box([0u8; 8192]).unwrap();
assert_eq!(boxed[0], 0);
} }
#[test]
fn test_frame_slice() {
let alloc = SmartAlloc::with_defaults();
alloc.begin_frame();
let mut slice = alloc.frame_slice::<u32>(100).unwrap();
assert_eq!(slice.len(), 100);
slice[0] = 42;
slice[99] = 123;
assert_eq!(slice[0], 42);
assert_eq!(slice[99], 123);
alloc.end_frame();
}
}