From 11fbf05968ba702b61b6c61e32fdd4250b2c0aba Mon Sep 17 00:00:00 2001 From: Manu Thambi Date: Wed, 18 Dec 2019 09:54:15 -0500 Subject: [PATCH] Use integer atomics for for u8, u16, u32, u64 to implement lockfree AtomicCell for types with those widths. Integer atomics are stable starting rust 1.34. Use autocfg to cleanup the detection of availability of atomics for both stable and nightly. Issue #454 --- crossbeam-utils/build.rs | 8 ++- crossbeam-utils/src/atomic/atomic_cell.rs | 68 ++++++++++------------- crossbeam-utils/tests/atomic_cell.rs | 17 +++--- 3 files changed, 43 insertions(+), 50 deletions(-) diff --git a/crossbeam-utils/build.rs b/crossbeam-utils/build.rs index d451c24b2..2f5012ad7 100644 --- a/crossbeam-utils/build.rs +++ b/crossbeam-utils/build.rs @@ -3,6 +3,12 @@ extern crate autocfg; fn main() { let cfg = autocfg::new(); if cfg.probe_rustc_version(1, 31) { - println!("cargo:rustc-cfg=has_min_const_fn"); + autocfg::emit("has_min_const_fn"); } + + cfg.emit_type_cfg("core::sync::atomic::AtomicU8", "has_atomic_u8"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU16", "has_atomic_u16"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU32", "has_atomic_u32"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU64", "has_atomic_u64"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU128", "has_atomic_u128"); } diff --git a/crossbeam-utils/src/atomic/atomic_cell.rs b/crossbeam-utils/src/atomic/atomic_cell.rs index 76aae65f8..cf0658aad 100644 --- a/crossbeam-utils/src/atomic/atomic_cell.rs +++ b/crossbeam-utils/src/atomic/atomic_cell.rs @@ -519,37 +519,28 @@ macro_rules! impl_arithmetic { } } }; - ($t:ty, $size:tt, $atomic:ty, $example:tt) => { - #[cfg(target_has_atomic = $size)] - impl_arithmetic!($t, $atomic, $example); - }; } -cfg_if! { - if #[cfg(feature = "nightly")] { - impl_arithmetic!(u8, "8", atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); - impl_arithmetic!(i8, "8", atomic::AtomicI8, "let a = AtomicCell::new(7i8);"); - impl_arithmetic!(u16, "16", atomic::AtomicU16, "let a = AtomicCell::new(7u16);"); - impl_arithmetic!(i16, "16", atomic::AtomicI16, "let a = AtomicCell::new(7i16);"); - impl_arithmetic!(u32, "32", atomic::AtomicU32, "let a = AtomicCell::new(7u32);"); - impl_arithmetic!(i32, "32", atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); - impl_arithmetic!(u64, "64", atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); - impl_arithmetic!(i64, "64", atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); - impl_arithmetic!(u128, "let a = AtomicCell::new(7u128);"); - impl_arithmetic!(i128, "let a = AtomicCell::new(7i128);"); - } else { - impl_arithmetic!(u8, "let a = AtomicCell::new(7u8);"); - impl_arithmetic!(i8, "let a = AtomicCell::new(7i8);"); - impl_arithmetic!(u16, "let a = AtomicCell::new(7u16);"); - impl_arithmetic!(i16, "let a = AtomicCell::new(7i16);"); - impl_arithmetic!(u32, "let a = AtomicCell::new(7u32);"); - impl_arithmetic!(i32, "let a = AtomicCell::new(7i32);"); - impl_arithmetic!(u64, "let a = AtomicCell::new(7u64);"); - impl_arithmetic!(i64, "let a = AtomicCell::new(7i64);"); - impl_arithmetic!(u128, "let a = AtomicCell::new(7u128);"); - impl_arithmetic!(i128, "let a = AtomicCell::new(7i128);"); - } -} +#[cfg(has_atomic_u8)] +impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); +#[cfg(has_atomic_u8)] +impl_arithmetic!(i8, atomic::AtomicI8, "let a = AtomicCell::new(7i8);"); +#[cfg(has_atomic_u16)] +impl_arithmetic!(u16, atomic::AtomicU16, "let a = AtomicCell::new(7u16);"); +#[cfg(has_atomic_u16)] +impl_arithmetic!(i16, atomic::AtomicI16, "let a = AtomicCell::new(7i16);"); +#[cfg(has_atomic_u32)] +impl_arithmetic!(u32, atomic::AtomicU32, "let a = AtomicCell::new(7u32);"); +#[cfg(has_atomic_u32)] +impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); +#[cfg(has_atomic_u64)] +impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); +#[cfg(has_atomic_u64)] +impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); +#[cfg(has_atomic_u128)] +impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); +#[cfg(has_atomic_u128)] +impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); impl_arithmetic!( usize, @@ -741,17 +732,14 @@ macro_rules! atomic { atomic!(@check, $t, AtomicUnit, $a, $atomic_op); atomic!(@check, $t, atomic::AtomicUsize, $a, $atomic_op); - #[cfg(feature = "nightly")] - { - #[cfg(target_has_atomic = "8")] - atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op); - #[cfg(target_has_atomic = "16")] - atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op); - #[cfg(target_has_atomic = "32")] - atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); - #[cfg(target_has_atomic = "64")] - atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); - } + #[cfg(has_atomic_u8)] + atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op); + #[cfg(has_atomic_u16)] + atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op); + #[cfg(has_atomic_u32)] + atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); + #[cfg(has_atomic_u64)] + atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); break $fallback_op; } diff --git a/crossbeam-utils/tests/atomic_cell.rs b/crossbeam-utils/tests/atomic_cell.rs index 57206aeda..e0b7db525 100644 --- a/crossbeam-utils/tests/atomic_cell.rs +++ b/crossbeam-utils/tests/atomic_cell.rs @@ -9,20 +9,19 @@ use crossbeam_utils::atomic::AtomicCell; fn is_lock_free() { struct UsizeWrap(usize); struct U8Wrap(bool); + struct I16Wrap(i16); assert_eq!(AtomicCell::::is_lock_free(), true); assert_eq!(AtomicCell::::is_lock_free(), true); assert_eq!(AtomicCell::::is_lock_free(), true); - assert_eq!(AtomicCell::::is_lock_free(), cfg!(feature = "nightly")); - assert_eq!( - AtomicCell::::is_lock_free(), - cfg!(feature = "nightly") - ); - assert_eq!( - AtomicCell::::is_lock_free(), - cfg!(feature = "nightly") - ); + assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u8)); + assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u8)); + assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u8)); + + assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u16)); + + assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u128)); } #[test]