//! std vs loom indirection for the modules that loom model-checks //! (`slot_state`, `run_queue`). Everything else uses std paths directly — //! the full runtime (context switches, futexes, real TLS) is not loom-able //! and is never executed under `cfg(loom)`. //! //! Build the loom models with: `RUSTFLAGS="--cfg loom" cargo test --lib --release` #[cfg(loom)] pub(crate) use loom::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; #[cfg(not(loom))] pub(crate) use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; /// `UnsafeCell` with loom's `with`/`with_mut` access API; pass-through cost /// is zero in normal builds (`#[inline]`, newtype over std's cell). #[cfg(loom)] pub(crate) use loom::cell::UnsafeCell; #[cfg(not(loom))] pub(crate) struct UnsafeCell(std::cell::UnsafeCell); #[cfg(not(loom))] impl UnsafeCell { pub(crate) fn new(v: T) -> Self { Self(std::cell::UnsafeCell::new(v)) } #[inline] pub(crate) fn with(&self, f: impl FnOnce(*const T) -> R) -> R { f(self.0.get()) } #[inline] pub(crate) fn with_mut(&self, f: impl FnOnce(*mut T) -> R) -> R { f(self.0.get()) } }