Skip to main content

kernel_api/
num.rs

1use core::fmt;
2#[cfg(all(target_pointer_width = "64", target_has_atomic_load_store = "128"))]
3use core::sync::atomic::AtomicU128;
4#[cfg(all(target_pointer_width = "32", target_has_atomic_load_store = "64"))]
5use core::sync::atomic::AtomicU64;
6#[cfg(any(
7	all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
8	all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
9))]
10use core::sync::atomic::Ordering;
11
12#[cfg(target_pointer_width = "64")]
13type UfatInner = u128;
14#[cfg(target_pointer_width = "32")]
15type UfatInner = u64;
16
17#[cfg(all(target_pointer_width = "64", target_has_atomic_load_store = "128"))]
18type AtomicUfatInner = AtomicU128;
19#[cfg(all(target_pointer_width = "32", target_has_atomic_load_store = "64"))]
20type AtomicUfatInner = AtomicU64;
21
22#[expect(non_camel_case_types, reason = "effective primitive type")]
23#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
24#[repr(transparent)]
25pub struct ufat(UfatInner);
26
27#[cfg(any(
28	all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
29	all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
30))]
31#[derive(Debug)]
32#[repr(transparent)]
33pub struct AtomicUfat(AtomicUfatInner);
34
35impl ufat {
36	pub const MIN: Self = Self(UfatInner::MIN);
37	pub const MAX: Self = Self(UfatInner::MAX);
38	pub const BITS: u32 = UfatInner::BITS;
39
40	pub const fn new(upper: usize, lower: usize) -> Self {
41		let upper = upper as UfatInner;
42		let lower = lower as UfatInner;
43		Self((upper << usize::BITS) | lower)
44	}
45
46	pub const fn upper(self) -> usize {
47		(self.0 >> usize::BITS) as usize
48	}
49
50	pub const fn lower(self) -> usize {
51		self.0 as usize
52	}
53
54	pub const fn truncate<T: const private::TruncateTarget<Self>>(self) -> T {
55		T::truncate_from(self)
56	}
57}
58
59impl fmt::Binary for ufat {
60	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61		<UfatInner as fmt::Binary>::fmt(&self.0, f)
62	}
63}
64
65impl fmt::Display for ufat {
66	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67		<UfatInner as fmt::Display>::fmt(&self.0, f)
68	}
69}
70
71impl fmt::LowerExp for ufat {
72	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73		<UfatInner as fmt::LowerExp>::fmt(&self.0, f)
74	}
75}
76
77impl fmt::LowerHex for ufat {
78	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79		<UfatInner as fmt::LowerHex>::fmt(&self.0, f)
80	}
81}
82
83impl fmt::Octal for ufat {
84	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85		<UfatInner as fmt::Octal>::fmt(&self.0, f)
86	}
87}
88
89impl fmt::UpperExp for ufat {
90	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91		<UfatInner as fmt::UpperExp>::fmt(&self.0, f)
92	}
93}
94
95impl fmt::UpperHex for ufat {
96	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97		<UfatInner as fmt::UpperHex>::fmt(&self.0, f)
98	}
99}
100
101#[cfg(any(
102	all(target_pointer_width = "64", target_has_atomic_load_store = "128"),
103	all(target_pointer_width = "32", target_has_atomic_load_store = "64"),
104))]
105impl AtomicUfat {
106	pub const fn new(v: ufat) -> Self { Self(AtomicUfatInner::new(v.0)) }
107	pub fn load(&self, ordering: Ordering) -> ufat { ufat(self.0.load(ordering)) }
108	pub fn store(&self, val: ufat, ordering: Ordering) { self.0.store(val.0, ordering); }
109	pub fn swap(&self, val: ufat, order: Ordering) -> ufat { ufat(self.0.swap(val.0, order)) }
110	pub fn compare_exchange(&self, current: ufat, new: ufat, success: Ordering, failure: Ordering) -> Result<ufat, ufat> {
111		self.0.compare_exchange(current.0, new.0, success, failure)
112			.map(ufat)
113			.map_err(ufat)
114	}
115	pub fn fetch_update<F>(&self, set_order: Ordering, fetch_order: Ordering, mut f: F) -> Result<ufat, ufat>
116	where
117		F: FnMut(ufat) -> Option<ufat>
118	{
119		self.0.fetch_update(set_order, fetch_order, |val| f(ufat(val)).map(|val| val.0))
120			.map(ufat)
121			.map_err(ufat)
122	}
123}
124
125mod private {
126	pub const trait TruncateTarget<T> {
127		fn truncate_from(val: T) -> Self;
128	}
129}
130
131const impl private::TruncateTarget<ufat> for usize {
132	fn truncate_from(val: ufat) -> Self { val.lower() }
133}
134
135const impl private::TruncateTarget<ufat> for u8 {
136	fn truncate_from(val: ufat) -> Self { val.0.truncate() }
137}
138
139const impl private::TruncateTarget<ufat> for u16 {
140	fn truncate_from(val: ufat) -> Self { val.0.truncate() }
141}
142
143const impl private::TruncateTarget<ufat> for u32 {
144	fn truncate_from(val: ufat) -> Self { val.0.truncate() }
145}