/rust/registry/src/index.crates.io-1949cf8c6b5b557f/region-3.0.2/src/page.rs
Line | Count | Source |
1 | | //! Page related functions. |
2 | | |
3 | | use crate::os; |
4 | | use std::sync::Once; |
5 | | |
6 | | /// Returns the operating system's page size. |
7 | | /// |
8 | | /// This function uses an internally cached page size, and can be called |
9 | | /// repeatedly without incurring a significant performance penalty. |
10 | | /// |
11 | | /// # Examples |
12 | | /// |
13 | | /// ``` |
14 | | /// # use region::page; |
15 | | /// let size = page::size(); // Most likely 4096 |
16 | | /// ``` |
17 | | #[inline] |
18 | 314k | pub fn size() -> usize { |
19 | | static INIT: Once = Once::new(); |
20 | | static mut PAGE_SIZE: usize = 0; |
21 | | |
22 | | unsafe { |
23 | 314k | INIT.call_once(|| PAGE_SIZE = os::page_size()); region::page::size::{closure#0}Line | Count | Source | 23 | 2 | INIT.call_once(|| PAGE_SIZE = os::page_size()); |
Unexecuted instantiation: region::page::size::{closure#0}Unexecuted instantiation: region::page::size::{closure#0}region::page::size::{closure#0}Line | Count | Source | 23 | 3 | INIT.call_once(|| PAGE_SIZE = os::page_size()); |
Unexecuted instantiation: region::page::size::{closure#0} |
24 | 314k | PAGE_SIZE |
25 | | } |
26 | 314k | } |
27 | | |
28 | | /// Rounds an address down to its closest page boundary. |
29 | | /// |
30 | | /// # Examples |
31 | | /// |
32 | | /// ``` |
33 | | /// # use region::page; |
34 | | /// let unaligned_pointer = (page::size() + 1) as *const (); |
35 | | /// |
36 | | /// assert_eq!(page::floor(unaligned_pointer), page::size() as *const _); |
37 | | /// ``` |
38 | | #[inline] |
39 | 45.5k | pub fn floor<T>(address: *const T) -> *const T { |
40 | 45.5k | (address as usize & !(size() - 1)) as *const T |
41 | 45.5k | } region::page::floor::<u8> Line | Count | Source | 39 | 27.7k | pub fn floor<T>(address: *const T) -> *const T { | 40 | 27.7k | (address as usize & !(size() - 1)) as *const T | 41 | 27.7k | } |
region::page::floor::<u8> Line | Count | Source | 39 | 574 | pub fn floor<T>(address: *const T) -> *const T { | 40 | 574 | (address as usize & !(size() - 1)) as *const T | 41 | 574 | } |
Unexecuted instantiation: region::page::floor::<_> region::page::floor::<u8> Line | Count | Source | 39 | 12.6k | pub fn floor<T>(address: *const T) -> *const T { | 40 | 12.6k | (address as usize & !(size() - 1)) as *const T | 41 | 12.6k | } |
region::page::floor::<u8> Line | Count | Source | 39 | 4.63k | pub fn floor<T>(address: *const T) -> *const T { | 40 | 4.63k | (address as usize & !(size() - 1)) as *const T | 41 | 4.63k | } |
|
42 | | |
43 | | /// Rounds an address up to its closest page boundary. |
44 | | /// |
45 | | /// # Examples |
46 | | /// |
47 | | /// ``` |
48 | | /// # use region::page; |
49 | | /// let unaligned_pointer = (page::size() - 1) as *const (); |
50 | | /// |
51 | | /// assert_eq!(page::ceil(unaligned_pointer), page::size() as *const _); |
52 | | /// ``` |
53 | | #[inline] |
54 | 45.5k | pub fn ceil<T>(address: *const T) -> *const T { |
55 | 45.5k | match (address as usize).checked_add(size()) { |
56 | 45.5k | Some(offset) => ((offset - 1) & !(size() - 1)) as *const T, |
57 | 0 | None => floor(address), |
58 | | } |
59 | 45.5k | } Line | Count | Source | 54 | 27.7k | pub fn ceil<T>(address: *const T) -> *const T { | 55 | 27.7k | match (address as usize).checked_add(size()) { | 56 | 27.7k | Some(offset) => ((offset - 1) & !(size() - 1)) as *const T, | 57 | 0 | None => floor(address), | 58 | | } | 59 | 27.7k | } |
Line | Count | Source | 54 | 574 | pub fn ceil<T>(address: *const T) -> *const T { | 55 | 574 | match (address as usize).checked_add(size()) { | 56 | 574 | Some(offset) => ((offset - 1) & !(size() - 1)) as *const T, | 57 | 0 | None => floor(address), | 58 | | } | 59 | 574 | } |
Unexecuted instantiation: region::page::ceil::<_> Line | Count | Source | 54 | 12.6k | pub fn ceil<T>(address: *const T) -> *const T { | 55 | 12.6k | match (address as usize).checked_add(size()) { | 56 | 12.6k | Some(offset) => ((offset - 1) & !(size() - 1)) as *const T, | 57 | 0 | None => floor(address), | 58 | | } | 59 | 12.6k | } |
Line | Count | Source | 54 | 4.63k | pub fn ceil<T>(address: *const T) -> *const T { | 55 | 4.63k | match (address as usize).checked_add(size()) { | 56 | 4.63k | Some(offset) => ((offset - 1) & !(size() - 1)) as *const T, | 57 | 0 | None => floor(address), | 58 | | } | 59 | 4.63k | } |
|
60 | | |
61 | | #[cfg(test)] |
62 | | mod tests { |
63 | | use super::*; |
64 | | |
65 | | #[test] |
66 | | fn page_size_is_reasonable() { |
67 | | let pz = size(); |
68 | | |
69 | | assert!(pz > 0); |
70 | | assert_eq!(pz % 2, 0); |
71 | | assert_eq!(pz, size()); |
72 | | } |
73 | | |
74 | | #[test] |
75 | | fn page_rounding_works() { |
76 | | let pz = size(); |
77 | | let point = 1 as *const (); |
78 | | |
79 | | assert_eq!(floor(point) as usize, 0); |
80 | | assert_eq!(floor(pz as *const ()) as usize, pz); |
81 | | assert_eq!(floor(usize::max_value() as *const ()) as usize % pz, 0); |
82 | | |
83 | | assert_eq!(ceil(point) as usize, pz); |
84 | | assert_eq!(ceil(pz as *const ()) as usize, pz); |
85 | | assert_eq!(ceil(usize::max_value() as *const ()) as usize % pz, 0); |
86 | | } |
87 | | } |