frozen_core/memmap/
page_size.rs1use crate::{
4 error::{FrozenError, FrozenResult},
5 hints,
6 memmap::err,
7};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30#[repr(usize)]
31pub enum PageSize {
32 K4 = 4096,
34 K16 = 16384,
36 K64 = 65536,
38}
39
40impl PageSize {
41 #[inline]
43 pub const fn as_usize(self) -> usize {
44 self as usize
45 }
46
47 #[inline]
49 pub const fn as_u32(self) -> u32 {
50 self as usize as u32
51 }
52
53 #[inline]
55 pub const fn is_power_of_two(self) -> bool {
56 true
57 }
58
59 pub fn validate_platform(self) -> FrozenResult<Self> {
68 Self::validate_target_platform(self, std::env::consts::OS, std::env::consts::ARCH)
69 }
70
71 pub(crate) fn validate_target_platform(self, os: &str, arch: &str) -> FrozenResult<Self> {
72 let valid = match (os, arch) {
73 ("windows", _) => self == Self::K4,
74 ("macos", "aarch64") => self == Self::K16,
75 ("macos", "x86_64") => self == Self::K4,
76 ("linux", "x86" | "x86_64") => self == Self::K4,
77 ("linux", "aarch64") => matches!(self, Self::K4 | Self::K16 | Self::K64),
78 _ => false,
79 };
80
81 if hints::likely(valid) {
82 Ok(self)
83 } else {
84 err::raw_error(
85 err::INV,
86 format!(
87 "unsupported page size {} for target platform {os}/{arch}",
88 self.as_usize()
89 ),
90 )
91 }
92 }
93}
94
95impl From<PageSize> for usize {
96 #[inline]
97 fn from(ps: PageSize) -> Self {
98 ps as usize
99 }
100}
101
102impl From<PageSize> for u32 {
103 #[inline]
104 fn from(ps: PageSize) -> Self {
105 ps as usize as u32
106 }
107}
108
109impl From<PageSize> for u64 {
110 #[inline]
111 fn from(ps: PageSize) -> Self {
112 ps as usize as u64
113 }
114}
115
116impl core::fmt::Display for PageSize {
117 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118 write!(f, "{}", self.as_usize())
119 }
120}
121
122impl TryFrom<usize> for PageSize {
123 type Error = FrozenError;
124
125 fn try_from(size: usize) -> Result<Self, Self::Error> {
126 match size {
127 4096 => Ok(Self::K4),
128 16384 => Ok(Self::K16),
129 65536 => Ok(Self::K64),
130 other => err::raw_error(err::INV, format!("unsupported page size: {other}")),
131 }
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn ok_page_size_conversions() {
141 assert_eq!(PageSize::K4.as_usize(), 4096);
142 assert_eq!(PageSize::K16.as_usize(), 16384);
143 assert_eq!(PageSize::K64.as_usize(), 65536);
144
145 assert_eq!(PageSize::K4.as_u32(), 4096);
146 assert_eq!(PageSize::K16.as_u32(), 16384);
147 assert_eq!(PageSize::K64.as_u32(), 65536);
148
149 assert_eq!(usize::from(PageSize::K4), 4096);
150 assert_eq!(u32::from(PageSize::K16), 16384);
151 assert_eq!(u64::from(PageSize::K64), 65536);
152
153 assert_eq!(PageSize::try_from(4096).unwrap(), PageSize::K4);
154 assert_eq!(PageSize::try_from(16384).unwrap(), PageSize::K16);
155 assert_eq!(PageSize::try_from(65536).unwrap(), PageSize::K64);
156
157 assert_eq!(format!("{}", PageSize::K4), "4096");
158 assert_eq!(format!("{}", PageSize::K16), "16384");
159 assert_eq!(format!("{}", PageSize::K64), "65536");
160
161 assert!(PageSize::K4.is_power_of_two());
162 assert!(PageSize::K16.is_power_of_two());
163 assert!(PageSize::K64.is_power_of_two());
164 }
165
166 #[test]
167 fn err_page_size_invalid_values() {
168 assert!(PageSize::try_from(0).is_err());
169 assert!(PageSize::try_from(1024).is_err());
170 assert!(PageSize::try_from(2048).is_err());
171 assert!(PageSize::try_from(5000).is_err());
172 assert!(PageSize::try_from(8192).is_err());
173 assert!(PageSize::try_from(32768).is_err());
174 assert!(PageSize::try_from(131072).is_err());
175 }
176
177 #[test]
178 fn ok_platform_validation_matrix() {
179 assert!(PageSize::K4.validate_target_platform("windows", "x86_64").is_ok());
181 assert!(PageSize::K4.validate_target_platform("windows", "aarch64").is_ok());
182 assert!(PageSize::K16.validate_target_platform("windows", "x86_64").is_err());
183 assert!(PageSize::K64.validate_target_platform("windows", "x86_64").is_err());
184
185 assert!(PageSize::K16.validate_target_platform("macos", "aarch64").is_ok());
187 assert!(PageSize::K4.validate_target_platform("macos", "aarch64").is_err());
188 assert!(PageSize::K64.validate_target_platform("macos", "aarch64").is_err());
189
190 assert!(PageSize::K4.validate_target_platform("macos", "x86_64").is_ok());
192 assert!(PageSize::K16.validate_target_platform("macos", "x86_64").is_err());
193 assert!(PageSize::K64.validate_target_platform("macos", "x86_64").is_err());
194
195 assert!(PageSize::K4.validate_target_platform("linux", "x86_64").is_ok());
197 assert!(PageSize::K4.validate_target_platform("linux", "x86").is_ok());
198 assert!(PageSize::K16.validate_target_platform("linux", "x86_64").is_err());
199 assert!(PageSize::K64.validate_target_platform("linux", "x86_64").is_err());
200
201 assert!(PageSize::K4.validate_target_platform("linux", "aarch64").is_ok());
203 assert!(PageSize::K16.validate_target_platform("linux", "aarch64").is_ok());
204 assert!(PageSize::K64.validate_target_platform("linux", "aarch64").is_ok());
205
206 assert!(PageSize::K4.validate_target_platform("freebsd", "x86_64").is_err());
208 assert!(PageSize::K4.validate_target_platform("unknown", "unknown").is_err());
209 }
210
211 #[test]
212 fn ok_current_platform_validation() {
213 #[cfg(all(target_os = "linux", any(target_arch = "x86", target_arch = "x86_64")))]
214 assert!(PageSize::K4.validate_platform().is_ok());
215
216 #[cfg(all(target_os = "linux", target_arch = "aarch64"))]
217 {
218 assert!(PageSize::K4.validate_platform().is_ok());
219 assert!(PageSize::K16.validate_platform().is_ok());
220 assert!(PageSize::K64.validate_platform().is_ok());
221 }
222
223 #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
224 {
225 assert!(PageSize::K16.validate_platform().is_ok());
226 assert!(PageSize::K4.validate_platform().is_err());
227 }
228
229 #[cfg(all(target_os = "macos", target_arch = "x86_64"))]
230 {
231 assert!(PageSize::K4.validate_platform().is_ok());
232 assert!(PageSize::K16.validate_platform().is_err());
233 }
234
235 #[cfg(target_os = "windows")]
236 {
237 assert!(PageSize::K4.validate_platform().is_ok());
238 assert!(PageSize::K16.validate_platform().is_err());
239 }
240 }
241}