1use crate::errors::{MmapIoError, Result};
4
5#[must_use]
7pub fn page_size() -> usize {
8 cfg_if::cfg_if! {
12 if #[cfg(target_os = "windows")] {
13 windows_page_size()
14 } else {
15 unix_page_size()
16 }
17 }
18}
19
20#[cfg(target_os = "windows")]
21fn windows_page_size() -> usize {
22 use std::mem::MaybeUninit;
23 #[allow(non_snake_case)]
24 #[repr(C)]
25 struct SYSTEM_INFO {
26 wProcessorArchitecture: u16,
27 wReserved: u16,
28 dwPageSize: u32,
29 lpMinimumApplicationAddress: *mut core::ffi::c_void,
30 lpMaximumApplicationAddress: *mut core::ffi::c_void,
31 dwActiveProcessorMask: usize,
32 dwNumberOfProcessors: u32,
33 dwProcessorType: u32,
34 dwAllocationGranularity: u32,
35 wProcessorLevel: u16,
36 wProcessorRevision: u16,
37 }
38 extern "system" {
39 fn GetSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
40 }
41 let mut sysinfo = MaybeUninit::<SYSTEM_INFO>::uninit();
42 unsafe {
43 GetSystemInfo(sysinfo.as_mut_ptr());
44 let s = sysinfo.assume_init();
45 s.dwPageSize as usize
46 }
47}
48
49#[cfg(not(target_os = "windows"))]
50#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
51fn unix_page_size() -> usize {
52 unsafe {
54 let page_size = libc::sysconf(libc::_SC_PAGESIZE);
55 page_size.max(0) as usize
58 }
59}
60
61#[must_use]
63pub fn align_up(value: u64, alignment: u64) -> u64 {
64 if alignment == 0 {
65 return value;
66 }
67 if alignment.is_power_of_two() {
69 let mask = alignment - 1;
70 (value + mask) & !mask
71 } else {
72 value.div_ceil(alignment) * alignment
73 }
74}
75
76pub fn ensure_in_bounds(offset: u64, len: u64, total: u64) -> Result<()> {
83 if offset > total {
84 return Err(MmapIoError::OutOfBounds { offset, len, total });
85 }
86 let end = offset.saturating_add(len);
87 if end > total {
88 return Err(MmapIoError::OutOfBounds { offset, len, total });
89 }
90 Ok(())
91}
92
93#[allow(clippy::cast_possible_truncation)]
99pub fn slice_range(offset: u64, len: u64, total: u64) -> Result<(usize, usize)> {
100 ensure_in_bounds(offset, len, total)?;
101 let start = offset as usize;
104 let end = (offset + len) as usize;
105 Ok((start, end))
106}