Skip to main content

kernel_api/allocator/
mod.rs

1//! Physical and virtual memory allocation
2
3mod pmm;
4
5use core::fmt;
6pub use pmm::*;
7
8mod vmm;
9pub use vmm::*;
10
11/// The error returned when an allocation was unsuccessful.
12///
13/// This will include a payload about the reason for failure.
14///
15/// # Examples
16///
17/// ```
18/// use kernel_api::allocator::highmem;
19///
20/// if let Err(e) = highmem().allocate_one() {
21///     info!("memory allocation failed: {e}");
22/// }
23/// ```
24#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
25#[non_exhaustive]
26pub struct AllocError {
27	provider: AllocProvider,
28}
29
30impl AllocError {
31	/// Constructs an `AllocError` caused by an error in physical memory allocation.
32	///
33	/// # Examples
34	///
35	/// ```
36	/// use kernel_api::allocator::AllocError;
37	///
38	/// let error = AllocError::pmm();
39	/// ```
40	#[must_use]
41	pub const fn pmm() -> Self { Self { provider: AllocProvider::Pmm } }
42
43	/// Constructs an `AllocError` caused by an error in virtual memory allocation.
44	///
45	/// # Examples
46	///
47	/// ```
48	/// use kernel_api::allocator::AllocError;
49	///
50	/// let error = AllocError::vmm();
51	/// ```
52	#[must_use]
53	pub const fn vmm() -> Self { Self { provider: AllocProvider::Vmm } }
54
55	/// Constructs an `AllocError` caused by an error in heap allocation.
56	///
57	/// # Examples
58	///
59	/// ```
60	/// use kernel_api::allocator::AllocError;
61	///
62	/// let error = AllocError::heap();
63	/// ```
64	#[must_use]
65	pub const fn heap() -> Self { Self { provider: AllocProvider::Heap } }
66}
67
68#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
69enum AllocProvider {
70	#[default]
71	None,
72	Pmm,
73	Vmm,
74	Heap,
75	Syscall(crate::syscall::Error),
76}
77
78impl From<crate::syscall::Error> for AllocError {
79	fn from(value: crate::syscall::Error) -> Self {
80		Self { provider: AllocProvider::Syscall(value) }
81	}
82}
83
84impl fmt::Display for AllocError {
85	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86		match self.provider {
87			AllocProvider::None => write!(f, "memory allocation failed"),
88			AllocProvider::Pmm => write!(f, "physical memory allocation failed"),
89			AllocProvider::Vmm => write!(f, "virtual memory allocation failed"),
90			AllocProvider::Heap => write!(f, "heap memory allocation failed"),
91			AllocProvider::Syscall(_) => write!(f, "memory allocation failed due to syscall error"),
92		}
93	}
94}
95
96impl core::error::Error for AllocError {
97	fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
98		match self.provider {
99			AllocProvider::Syscall(ref error) => Some(error),
100			_ => None,
101		}
102	}
103}