1 use crate::{AcpiError, AcpiResult}; 2 use core::{ 3 alloc::{Allocator, Layout}, 4 mem, 5 ptr::NonNull, 6 }; 7 8 /// Thin wrapper around a regular slice, taking a reference to an allocator for automatic 9 /// deallocation when the slice is dropped out of scope. 10 #[derive(Debug)] 11 pub struct ManagedSlice<'a, T, A> 12 where 13 A: Allocator, 14 { 15 slice: &'a mut [T], 16 allocator: A, 17 } 18 19 impl<'a, T, A> ManagedSlice<'a, T, A> 20 where 21 A: Allocator, 22 { 23 /// Attempt to allocate a new `ManagedSlice` that holds `len` `T`s. new_in(len: usize, allocator: A) -> AcpiResult<Self>24 pub fn new_in(len: usize, allocator: A) -> AcpiResult<Self> { 25 let layout = Layout::array::<T>(len).map_err(|_| AcpiError::AllocError)?; 26 match allocator.allocate(layout) { 27 Ok(mut ptr) => { 28 let slice = unsafe { core::slice::from_raw_parts_mut(ptr.as_mut().as_mut_ptr().cast(), len) }; 29 Ok(ManagedSlice { slice, allocator }) 30 } 31 Err(_) => Err(AcpiError::AllocError), 32 } 33 } 34 } 35 36 #[cfg(feature = "alloc")] 37 impl<'a, T> ManagedSlice<'a, T, alloc::alloc::Global> { new(len: usize) -> AcpiResult<Self>38 pub fn new(len: usize) -> AcpiResult<Self> { 39 Self::new_in(len, alloc::alloc::Global) 40 } 41 } 42 43 impl<'a, T, A> Drop for ManagedSlice<'a, T, A> 44 where 45 A: Allocator, 46 { drop(&mut self)47 fn drop(&mut self) { 48 unsafe { 49 let slice_ptr = NonNull::new_unchecked(self.slice.as_ptr().cast_mut().cast::<u8>()); 50 let slice_layout = 51 Layout::from_size_align_unchecked(mem::size_of_val(self.slice), mem::align_of_val(self.slice)); 52 self.allocator.deallocate(slice_ptr, slice_layout); 53 } 54 } 55 } 56 57 impl<'a, T, A> core::ops::Deref for ManagedSlice<'a, T, A> 58 where 59 A: Allocator, 60 { 61 type Target = [T]; 62 deref(&self) -> &Self::Target63 fn deref(&self) -> &Self::Target { 64 self.slice 65 } 66 } 67 68 impl<'a, T, A> core::ops::DerefMut for ManagedSlice<'a, T, A> 69 where 70 A: Allocator, 71 { deref_mut(&mut self) -> &mut Self::Target72 fn deref_mut(&mut self) -> &mut Self::Target { 73 self.slice 74 } 75 } 76