|
1 |
| -use core::{alloc, mem}; |
| 1 | +use crate::{AcpiError, AcpiResult}; |
| 2 | +use core::{ |
| 3 | + alloc::{Allocator, Layout}, |
| 4 | + mem, |
| 5 | + ptr::NonNull, |
| 6 | +}; |
2 | 7 |
|
3 | 8 | /// Thin wrapper around a regular slice, taking a reference to an allocator for automatic
|
4 | 9 | /// deallocation when the slice is dropped out of scope.
|
5 | 10 | #[derive(Debug)]
|
6 | 11 | pub struct ManagedSlice<'a, T, A>
|
7 | 12 | where
|
8 |
| - A: alloc::Allocator, |
| 13 | + A: Allocator, |
9 | 14 | {
|
10 | 15 | slice: &'a mut [T],
|
11 | 16 | allocator: A,
|
12 | 17 | }
|
13 | 18 |
|
14 | 19 | impl<'a, T, A> ManagedSlice<'a, T, A>
|
15 | 20 | where
|
16 |
| - A: alloc::Allocator, |
| 21 | + A: Allocator, |
17 | 22 | {
|
18 |
| - /// Attempts to allocate a new `&mut [T]` in the given allocator. |
19 |
| - pub fn new_in(len: usize, allocator: A) -> crate::AcpiResult<Self> { |
20 |
| - // Safety: Type automatically deallocated memory on `Drop` and; |
21 |
| - // Constructed slice is from valid, aligned, allocated memory. |
22 |
| - unsafe { |
23 |
| - allocator |
24 |
| - .allocate(alloc::Layout::array::<T>(len).map_err(|_| crate::AcpiError::AllocError)?) |
25 |
| - .map(|mut ptr| core::slice::from_raw_parts_mut(ptr.as_mut().as_mut_ptr().cast(), len)) |
26 |
| - .map(|slice| Self { slice, allocator }) |
27 |
| - .map_err(|_| crate::AcpiError::AllocError) |
| 23 | + /// Attempt to allocate a new `ManagedSlice` that holds `len` `T`s. |
| 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), |
28 | 32 | }
|
29 | 33 | }
|
30 | 34 | }
|
31 | 35 |
|
32 | 36 | impl<'a, T, A> Drop for ManagedSlice<'a, T, A>
|
33 | 37 | where
|
34 |
| - A: alloc::Allocator, |
| 38 | + A: Allocator, |
35 | 39 | {
|
36 | 40 | fn drop(&mut self) {
|
37 |
| - // Safety: Slice is required by function to point to non-null memory. |
38 |
| - let slice_ptr = unsafe { core::ptr::NonNull::new_unchecked(self.slice.as_ptr().cast_mut().cast::<u8>()) }; |
39 |
| - // Safety: Slice is constructed from a valid layout. |
40 |
| - let slice_layout = unsafe { |
41 |
| - alloc::Layout::from_size_align_unchecked(mem::size_of_val(self.slice), mem::align_of_val(self.slice)) |
42 |
| - }; |
43 |
| - |
44 |
| - // Safety: Caller is required to provide a slice allocated with the provided allocator. |
45 |
| - unsafe { self.allocator.deallocate(slice_ptr, slice_layout) }; |
| 41 | + unsafe { |
| 42 | + let slice_ptr = NonNull::new_unchecked(self.slice.as_ptr().cast_mut().cast::<u8>()); |
| 43 | + let slice_layout = |
| 44 | + Layout::from_size_align_unchecked(mem::size_of_val(self.slice), mem::align_of_val(self.slice)); |
| 45 | + self.allocator.deallocate(slice_ptr, slice_layout); |
| 46 | + } |
46 | 47 | }
|
47 | 48 | }
|
48 | 49 |
|
49 | 50 | impl<'a, T, A> core::ops::Deref for ManagedSlice<'a, T, A>
|
50 | 51 | where
|
51 |
| - A: alloc::Allocator, |
| 52 | + A: Allocator, |
52 | 53 | {
|
53 | 54 | type Target = [T];
|
54 | 55 |
|
|
59 | 60 |
|
60 | 61 | impl<'a, T, A> core::ops::DerefMut for ManagedSlice<'a, T, A>
|
61 | 62 | where
|
62 |
| - A: alloc::Allocator, |
| 63 | + A: Allocator, |
63 | 64 | {
|
64 | 65 | fn deref_mut(&mut self) -> &mut Self::Target {
|
65 | 66 | self.slice
|
|
0 commit comments