cacheguard/
lib.rs

1#![no_std]
2// for target_archs that are nightly only
3#![allow(unexpected_cfgs)]
4use core::{fmt, ops::Deref, ops::DerefMut};
5#[derive(Clone, Copy, Default, Hash, PartialEq, Eq)]
6#[cfg_attr(target_arch = "msp430", repr(align(8)))]
7#[cfg_attr(target_arch = "m68k", repr(align(16)))]
8#[cfg_attr(
9    any(
10        target_arch = "arm",
11        target_arch = "avr",
12        target_arch = "hexagon",
13        target_arch = "mips",
14        target_arch = "mips32r6",
15        target_arch = "riscv32",
16        target_arch = "riscv64",
17        target_arch = "sparc",
18        target_arch = "xtensa",
19    ),
20    repr(align(32))
21)]
22#[cfg_attr(
23    any(
24        target_arch = "aarch64",
25        target_arch = "amdgpu",
26        target_arch = "arm64ec",
27        target_arch = "mips64",
28        target_arch = "mips64r6",
29        target_arch = "nvptx64",
30        target_arch = "powerpc",
31        target_arch = "powerpc64",
32        target_arch = "wasm32",
33        target_arch = "wasm64",
34        target_arch = "x86_64",
35    ),
36    repr(align(128))
37)]
38#[cfg_attr(target_arch = "s390x", repr(align(256)))]
39// Defaults to 64-byte alignment for targets such as bpf, csky, loongarch64, sparc64, x86 and all
40// the others
41#[cfg_attr(
42    not(any(
43        target_arch = "aarch64",
44        target_arch = "amdgpu",
45        target_arch = "arm",
46        target_arch = "arm64ec",
47        target_arch = "avr",
48        target_arch = "hexagon",
49        target_arch = "m68k",
50        target_arch = "mips",
51        target_arch = "mips32r6",
52        target_arch = "mips64",
53        target_arch = "mips64r6",
54        target_arch = "msp430",
55        target_arch = "nvptx64",
56        target_arch = "powerpc",
57        target_arch = "powerpc64",
58        target_arch = "riscv32",
59        target_arch = "riscv64",
60        target_arch = "s390x",
61        target_arch = "sparc",
62        target_arch = "wasm32",
63        target_arch = "wasm64",
64        target_arch = "x86_64",
65        target_arch = "xtensa",
66    )),
67    repr(align(64))
68)]
69// CacheGuard is primarily used to pad atomic variables to prevent cache
70// invalidation that can occur due to atomic operations. By aligning memory
71// according to the target architecture's cache size rules, CacheGuard mitigates
72// false sharing and enhances performance, particularly in concurrent
73// environments.
74pub struct CacheGuard<T> {
75    inner: T,
76}
77/// Creates a new `CacheGuard` instance that wraps the provided value.
78///
79/// This function is a constructor for `CacheGuard`. It takes ownership of the
80/// input value and returns a new `CacheGuard` instance containing that value.
81///
82/// # Examples
83///
84/// ```rust
85/// use cacheguard::CacheGuard;
86/// use core::sync::atomic::AtomicUsize;
87/// let cache_guard = CacheGuard::new(AtomicUsize::new(0));
88/// ```
89///
90/// # Parameters
91///
92/// - `inner`: The value to be wrapped within the `CacheGuard`.
93impl<T> CacheGuard<T> {
94    pub const fn new(inner: T) -> CacheGuard<T> {
95        CacheGuard::<T> { inner }
96    }
97    pub fn into_inner(self) -> T {
98        self.inner
99    }
100}
101impl<T: fmt::Debug> fmt::Debug for CacheGuard<T> {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        f.debug_struct("CacheGuard")
104            .field("inner", &self.inner)
105            .finish()
106    }
107}
108impl<T: fmt::Display> fmt::Display for CacheGuard<T> {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        fmt::Display::fmt(&self.inner, f)
111    }
112}
113impl<T> From<T> for CacheGuard<T> {
114    fn from(t: T) -> CacheGuard<T> {
115        CacheGuard::new(t)
116    }
117}
118impl<T> Deref for CacheGuard<T> {
119    type Target = T;
120    fn deref(&self) -> &T {
121        &self.inner
122    }
123}
124impl<T> DerefMut for CacheGuard<T> {
125    fn deref_mut(&mut self) -> &mut T {
126        &mut self.inner
127    }
128}
129unsafe impl<T: Send> Send for CacheGuard<T> {}
130unsafe impl<T: Sync> Sync for CacheGuard<T> {}