// Copyright 2025 Jonas Kruckenberg // // Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be // copied, modified, or distributed except according to those terms. use core::ops::{Deref, DerefMut}; /// `CachePadded` wraps an inner type `T` applying architecture-specific padding to ensure the type /// takes up exactly one cache line on the target architecture. This avoids [false sharing]. /// /// The cache padding rules are copied from crossbeam-utils/src/cache_padded.rs /// /// Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache /// lines at a time, so we have to align to 128 bytes rather than 64. /// /// Sources: /// - /// - /// /// ARM's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size. /// /// Sources: /// - /// /// powerpc64 has 128-byte cache line size. /// /// Sources: /// - /// /// [false sharing]: #[cfg_attr( any( target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64", ), repr(align(128)) )] /// /// arm, mips, mips64, sparc, and hexagon have 32-byte cache line size. /// /// Sources: /// - /// - /// - /// - /// - /// - #[cfg_attr( any( target_arch = "arm", target_arch = "mips", target_arch = "mips64", target_arch = "sparc", target_arch = "hexagon", ), repr(align(32)) )] /// /// m68k has 16-byte cache line size. /// /// Sources: /// - #[cfg_attr(target_arch = "m68k", repr(align(16)))] /// /// s390x has 256-byte cache line size. /// /// Sources: /// - /// - #[cfg_attr(target_arch = "s390x", repr(align(256)))] /// /// x86, riscv, wasm, and sparc64 have 64-byte cache line size. /// /// Sources: /// - /// - /// - /// - /// /// All others are assumed to have 64-byte cache line size. #[cfg_attr( not(any( target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "arm", target_arch = "mips", target_arch = "mips64", target_arch = "sparc", target_arch = "hexagon", target_arch = "m68k", target_arch = "s390x", )), repr(align(64)) )] #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct CachePadded(pub T); impl Deref for CachePadded { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for CachePadded { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl From for CachePadded { fn from(value: T) -> Self { Self(value) } }