pub const CACHE_LINE_SIZE: usize = 64;
#[must_use]
pub const fn align_to_cache_line(size: usize) -> usize {
(size + CACHE_LINE_SIZE - 1) & !(CACHE_LINE_SIZE - 1)
}
#[repr(align(64))]
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CacheAligned<T>(pub T);
impl<T> CacheAligned<T> {
pub const fn new(value: T) -> Self {
Self(value)
}
pub const fn get(&self) -> &T {
&self.0
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> core::ops::Deref for CacheAligned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> core::ops::DerefMut for CacheAligned<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: core::fmt::Debug> core::fmt::Debug for CacheAligned<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("CacheAligned")
.field("value", &self.0)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cache_line_alignment() {
assert_eq!(align_to_cache_line(1), 64);
assert_eq!(align_to_cache_line(64), 64);
assert_eq!(align_to_cache_line(65), 128);
}
#[test]
fn test_cache_aligned_wrapper() {
let aligned = CacheAligned::new(42);
assert_eq!(*aligned, 42);
assert_eq!(aligned.get(), &42);
}
}