mmtk/util/metadata/
metadata_val_traits.rs1use crate::util::Address;
2use core::sync::atomic::*;
3use num_traits::{FromPrimitive, ToPrimitive};
4use num_traits::{Unsigned, WrappingAdd, WrappingSub, Zero};
5
6pub trait Bits {
9 const BITS: u32;
11 const LOG2: u32;
13}
14macro_rules! impl_bits_trait {
15 ($t: ty) => {
16 impl Bits for $t {
17 const BITS: u32 = <$t>::BITS;
18 const LOG2: u32 = Self::BITS.trailing_zeros();
19 }
20 };
21}
22impl_bits_trait!(u8);
23impl_bits_trait!(u16);
24impl_bits_trait!(u32);
25impl_bits_trait!(u64);
26impl_bits_trait!(usize);
27
28pub trait BitwiseOps {
31 fn bitand(self, other: Self) -> Self;
33 fn bitor(self, other: Self) -> Self;
35 fn bitxor(self, other: Self) -> Self;
37 fn inv(self) -> Self;
39}
40macro_rules! impl_bitwise_ops_trait {
41 ($t: ty) => {
42 impl BitwiseOps for $t {
43 fn bitand(self, other: Self) -> Self {
44 self & other
45 }
46 fn bitor(self, other: Self) -> Self {
47 self | other
48 }
49 fn bitxor(self, other: Self) -> Self {
50 self ^ other
51 }
52 fn inv(self) -> Self {
53 !self
54 }
55 }
56 };
57}
58impl_bitwise_ops_trait!(u8);
59impl_bitwise_ops_trait!(u16);
60impl_bitwise_ops_trait!(u32);
61impl_bitwise_ops_trait!(u64);
62impl_bitwise_ops_trait!(usize);
63
64pub trait MetadataValue:
68 Unsigned
69 + Zero
70 + WrappingAdd
71 + WrappingSub
72 + Bits
73 + BitwiseOps
74 + ToPrimitive
75 + Copy
76 + FromPrimitive
77 + std::fmt::Display
78 + std::fmt::Debug
79{
80 unsafe fn load(addr: Address) -> Self;
85
86 unsafe fn load_atomic(addr: Address, order: Ordering) -> Self;
90
91 unsafe fn store(addr: Address, value: Self);
96
97 unsafe fn store_atomic(addr: Address, value: Self, order: Ordering);
102
103 unsafe fn compare_exchange(
106 addr: Address,
107 current: Self,
108 new: Self,
109 success: Ordering,
110 failure: Ordering,
111 ) -> Result<Self, Self>;
112
113 unsafe fn fetch_add(addr: Address, value: Self, order: Ordering) -> Self;
116
117 unsafe fn fetch_sub(addr: Address, value: Self, order: Ordering) -> Self;
120
121 unsafe fn fetch_and(addr: Address, value: Self, order: Ordering) -> Self;
124
125 unsafe fn fetch_or(addr: Address, value: Self, order: Ordering) -> Self;
128
129 unsafe fn fetch_update<F>(
132 addr: Address,
133 set_order: Ordering,
134 fetch_order: Ordering,
135 f: F,
136 ) -> Result<Self, Self>
137 where
138 F: FnMut(Self) -> Option<Self>;
139}
140macro_rules! impl_metadata_value_trait {
141 ($non_atomic: ty, $atomic: ty) => {
142 impl MetadataValue for $non_atomic {
143 unsafe fn load(addr: Address) -> Self {
144 addr.load::<$non_atomic>()
145 }
146
147 unsafe fn load_atomic(addr: Address, order: Ordering) -> Self {
148 addr.as_ref::<$atomic>().load(order)
149 }
150
151 unsafe fn store(addr: Address, value: Self) {
152 addr.store::<$non_atomic>(value)
153 }
154
155 unsafe fn store_atomic(addr: Address, value: Self, order: Ordering) {
156 addr.as_ref::<$atomic>().store(value, order)
157 }
158
159 unsafe fn compare_exchange(
160 addr: Address,
161 current: Self,
162 new: Self,
163 success: Ordering,
164 failure: Ordering,
165 ) -> Result<Self, Self> {
166 addr.as_ref::<$atomic>()
167 .compare_exchange(current, new, success, failure)
168 }
169
170 unsafe fn fetch_add(addr: Address, value: Self, order: Ordering) -> Self {
171 addr.as_ref::<$atomic>().fetch_add(value, order)
172 }
173
174 unsafe fn fetch_sub(addr: Address, value: Self, order: Ordering) -> Self {
175 addr.as_ref::<$atomic>().fetch_sub(value, order)
176 }
177
178 unsafe fn fetch_and(addr: Address, value: Self, order: Ordering) -> Self {
179 addr.as_ref::<$atomic>().fetch_and(value, order)
180 }
181
182 unsafe fn fetch_or(addr: Address, value: Self, order: Ordering) -> Self {
183 addr.as_ref::<$atomic>().fetch_or(value, order)
184 }
185
186 unsafe fn fetch_update<F>(
187 addr: Address,
188 set_order: Ordering,
189 fetch_order: Ordering,
190 f: F,
191 ) -> Result<Self, Self>
192 where
193 F: FnMut(Self) -> Option<Self>,
194 {
195 addr.as_ref::<$atomic>()
196 .fetch_update(set_order, fetch_order, f)
197 }
198 }
199 };
200}
201impl_metadata_value_trait!(u8, AtomicU8);
202impl_metadata_value_trait!(u16, AtomicU16);
203impl_metadata_value_trait!(u32, AtomicU32);
204impl_metadata_value_trait!(u64, AtomicU64);
205impl_metadata_value_trait!(usize, AtomicUsize);