1#[cfg(feature = "nightly")]
2use core::alloc::{AllocError as CoreAllocError, Allocator as CoreAllocator};
3use core::{
4 alloc::{GlobalAlloc, Layout},
5 ptr::NonNull,
6};
7
8use allocator_api2::alloc::{AllocError, Allocator};
9use enumset::EnumSet;
10
11use crate::MemoryCapability;
12
13fn allocate_caps(
14 capabilities: EnumSet<MemoryCapability>,
15 layout: Layout,
16) -> Result<NonNull<[u8]>, AllocError> {
17 let raw_ptr = unsafe { crate::HEAP.alloc_caps(capabilities, layout) };
18 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
19 Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
20}
21
22use crate::EspHeap;
23
24unsafe impl Allocator for EspHeap {
25 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
26 let raw_ptr = unsafe { self.alloc(layout) };
27 let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?;
28 Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
29 }
30
31 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
32 unsafe {
33 crate::HEAP.dealloc(ptr.as_ptr(), layout);
34 }
35 }
36}
37
38#[cfg(feature = "nightly")]
39unsafe impl CoreAllocator for EspHeap {
40 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, CoreAllocError> {
41 let raw_ptr = unsafe { self.alloc(layout) };
42 let ptr = NonNull::new(raw_ptr).ok_or(CoreAllocError)?;
43 Ok(NonNull::slice_from_raw_parts(ptr, layout.size()))
44 }
45
46 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
47 unsafe {
48 crate::HEAP.dealloc(ptr.as_ptr(), layout);
49 }
50 }
51}
52
53pub struct AnyMemory;
55
56unsafe impl Allocator for AnyMemory {
57 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
58 allocate_caps(EnumSet::empty(), layout)
59 }
60
61 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
62 unsafe {
63 crate::HEAP.dealloc(ptr.as_ptr(), layout);
64 }
65 }
66}
67
68#[cfg(feature = "nightly")]
69unsafe impl CoreAllocator for AnyMemory {
70 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, CoreAllocError> {
71 allocate_caps(EnumSet::empty(), layout).map_err(|_| CoreAllocError)
72 }
73
74 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
75 unsafe {
76 crate::HEAP.dealloc(ptr.as_ptr(), layout);
77 }
78 }
79}
80
81pub struct InternalMemory;
83
84unsafe impl Allocator for InternalMemory {
85 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
86 allocate_caps(EnumSet::from(MemoryCapability::Internal), layout)
87 }
88
89 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
90 unsafe {
91 crate::HEAP.dealloc(ptr.as_ptr(), layout);
92 }
93 }
94}
95
96#[cfg(feature = "nightly")]
97unsafe impl CoreAllocator for InternalMemory {
98 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, CoreAllocError> {
99 allocate_caps(EnumSet::from(MemoryCapability::Internal), layout).map_err(|_| CoreAllocError)
100 }
101
102 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
103 unsafe {
104 crate::HEAP.dealloc(ptr.as_ptr(), layout);
105 }
106 }
107}
108
109pub struct ExternalMemory;
111
112unsafe impl Allocator for ExternalMemory {
113 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
114 allocate_caps(EnumSet::from(MemoryCapability::External), layout)
115 }
116
117 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
118 unsafe {
119 crate::HEAP.dealloc(ptr.as_ptr(), layout);
120 }
121 }
122}
123
124#[cfg(feature = "nightly")]
125unsafe impl CoreAllocator for ExternalMemory {
126 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, CoreAllocError> {
127 allocate_caps(EnumSet::from(MemoryCapability::External), layout).map_err(|_| CoreAllocError)
128 }
129
130 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
131 unsafe {
132 crate::HEAP.dealloc(ptr.as_ptr(), layout);
133 }
134 }
135}