kernel_api/memory/
allocator.rs1#![stable(feature = "kernel_core_api", since = "1.0.0")]
4
5use core::num::NonZero;
6use core::ops::Range;
7use auto_impl::auto_impl;
8
9use super::{Frame, AllocError, PAGE_SIZE};
10
11#[unstable(feature = "kernel_allocation_zeroing", issue = "2")]
13#[derive(Debug, Eq, PartialEq)]
14pub enum ZeroAllocError {
15 AllocError,
17 Uninit(Frame),
19}
20
21#[unstable(feature = "kernel_allocation_zeroing", issue = "2")]
22#[doc(hidden)]
23impl From<AllocError> for ZeroAllocError {
24 fn from(_: AllocError) -> Self { Self::AllocError }
25}
26
27#[unstable(feature = "kernel_allocation_new", issue = "5")]
29pub struct Config<'a> {
30 pub allocation_range: Range<Frame>,
34
35 pub regions: &'a mut dyn Iterator<Item = Range<Frame>>
37}
38
39#[unstable(feature = "kernel_allocation_new", issue = "5")]
40#[non_exhaustive]
41pub struct AllocationMeta {
42 pub region: Range<Frame>
43}
44
45impl AllocationMeta {
46 #[unstable(feature = "kernel_allocation_new", issue = "5")]
47 pub fn new(region: Range<Frame>) -> Self {
48 Self { region }
49 }
50}
51
52#[unstable(feature = "kernel_physical_allocator_non_contiguous", issue = "none")]
53pub struct AllocateNonContiguousRet(Range<Frame>);
54
55#[unstable(feature = "kernel_physical_allocator_non_contiguous", issue = "none")]
56impl IntoIterator for AllocateNonContiguousRet {
57 type Item = Frame;
58 type IntoIter = Range<Frame>;
59
60 fn into_iter(self) -> Self::IntoIter { self.0 }
61}
62
63#[auto_impl(&, Box, Arc)]
68#[stable(feature = "kernel_core_api", since = "1.0.0")]
69pub unsafe trait PhysicalAllocator: Send + Sync {
70 #[unstable(feature = "kernel_physical_allocator_non_contiguous", issue = "none")]
89 fn allocate(&self, frame_count: usize) -> Result<AllocateNonContiguousRet, AllocError> {
90 let base = self.allocate_contiguous(frame_count)?;
91 Ok(AllocateNonContiguousRet(base..(base + frame_count)))
92 }
93
94 #[stable(feature = "kernel_core_api", since = "1.0.0")]
96 fn allocate_contiguous(&self, frame_count: usize) -> Result<Frame, AllocError>;
97
98 #[stable(feature = "kernel_core_api", since = "1.0.0")]
100 fn allocate_one(&self) -> Result<Frame, AllocError> {
101 let frame = self.allocate(1)?;
102 Ok(frame.into_iter().next().expect("`allocate(1)` must return one frame"))
103 }
104
105 #[unstable(feature = "kernel_allocation_zeroing", issue = "2")]
107 fn try_allocate_zeroed(&self, frame_count: usize) -> Result<Frame, ZeroAllocError> { Err(ZeroAllocError::Uninit(self.allocate_contiguous(frame_count)?)) }
108
109 #[unstable(feature = "kernel_allocation_zeroing", issue = "2")]
111 fn allocate_zeroed(&self, frame_count: usize) -> Result<Frame, AllocError> {
112 #[cold]
113 fn do_zero(frame: Frame, frame_count: usize) {
114 let page = frame.to_page();
115
116 unsafe {
117 core::ptr::write_bytes(
118 page.as_ptr(),
119 0,
120 frame_count * PAGE_SIZE
121 );
122 }
123 }
124
125 let frames = self.try_allocate_zeroed(frame_count);
126 match frames {
127 Ok(frame) => Ok(frame),
128 Err(ZeroAllocError::AllocError) => Err(AllocError),
129 Err(ZeroAllocError::Uninit(frame)) => {
130 do_zero(frame, frame_count);
131 Ok(frame)
132 }
133 }
134 }
135
136 #[stable(feature = "kernel_core_api", since = "1.0.0")]
139 unsafe fn deallocate_contiguous(&self, base: Frame, frame_count: NonZero<usize>);
140
141 #[unstable(feature = "kernel_allocation_new", issue = "5")]
142 fn push(&mut self, _allocation: AllocationMeta) { unimplemented!("experimental") }
143
144 #[unstable(feature = "kernel_physical_allocator_location", issue = "none")]
145 fn allocate_at(&self, frame_count: usize, location: SpecificLocation) -> Result<Frame, AllocError>;
146}
147
148#[unstable(feature = "kernel_allocation_new", issue = "5")]
149pub unsafe trait SizedBackingAllocator: PhysicalAllocator + Sized {
150 #[unstable(feature = "kernel_allocation_new", issue = "5")]
151 fn new(config: Config) -> &'static mut dyn PhysicalAllocator;
152}
153
154#[unstable(feature = "kernel_physical_allocator_location", issue = "none")]
155pub enum SpecificLocation {
156 Aligned(NonZero<u32>),
158 At(Frame),
160 Below { location: Frame, with_alignment: NonZero<u32> }
162}
163
164#[unstable(feature = "kernel_physical_allocator_location", issue = "none")]
165pub enum Location {
166 Any,
167 Specific(SpecificLocation)
168}
169
170#[unstable(feature = "kernel_physical_allocator_location", issue = "none")]
171pub enum AlignError {
172 OomError,
173 Unaligned(AllocateNonContiguousRet)
174}