From c38532507e1e01edeeb3dbe385c83a15578ddefe Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 27 May 2021 20:07:58 +0900 Subject: [PATCH] Remove uses of autocfg Detect platforms that do not support AtomicU64 by using the same way. AFAIK, this is more robust than the current way that uses autocfg. See also https://github.com/rust-lang/futures-rs/pull/2294. --- ci/no_atomic.sh | 25 +++++++++++++ crossbeam-utils/Cargo.toml | 3 -- crossbeam-utils/build.rs | 25 +++---------- crossbeam-utils/src/atomic/atomic_cell.rs | 44 +++++++++-------------- crossbeam-utils/src/atomic/consume.rs | 10 ++---- crossbeam-utils/src/lib.rs | 6 +--- crossbeam-utils/tests/atomic_cell.rs | 22 +++++++----- no_atomic.rs | 41 +++++++++++++++++++++ 8 files changed, 104 insertions(+), 72 deletions(-) diff --git a/ci/no_atomic.sh b/ci/no_atomic.sh index b589dbb17..c423ea3c4 100755 --- a/ci/no_atomic.sh +++ b/ci/no_atomic.sh @@ -26,6 +26,31 @@ for target in $(rustc --print target-list); do done echo "];" >>"$file" +{ + # Only crossbeam-utils actually uses this const. + echo "#[allow(dead_code)]" + echo "const NO_ATOMIC_64: &[&str] = &[" +} >>"$file" +for target in $(rustc --print target-list); do + res=$(rustc --print target-spec-json -Z unstable-options --target "$target" \ + | jq -r "select(.\"max-atomic-width\" == 32)") + [[ -z "$res" ]] || echo " \"$target\"," >>"$file" +done +# It is not clear exactly what `"max-atomic-width" == null` means, but they +# actually seem to have the same max-atomic-width as the target-pointer-width. +# The targets currently included in this group are "mipsel-sony-psp", +# "thumbv4t-none-eabi", "thumbv6m-none-eabi", all of which are +# `"target-pointer-width" == "32"`, so assuming them `"max-atomic-width" == 32` +# for now. +for target in $(rustc --print target-list); do + res=$(rustc --print target-spec-json -Z unstable-options --target "$target" \ + | jq -r "select(.\"max-atomic-width\" == null)") + [[ -z "$res" ]] || echo " \"$target\"," >>"$file" +done +echo "];" >>"$file" + +# There is no `"max-atomic-width" == 16` or `"max-atomic-width" == 8` targets. + # `"max-atomic-width" == 0` means that atomic is not supported at all. { # Only crossbeam-utils actually uses this const. diff --git a/crossbeam-utils/Cargo.toml b/crossbeam-utils/Cargo.toml index 212671e59..14526cadf 100644 --- a/crossbeam-utils/Cargo.toml +++ b/crossbeam-utils/Cargo.toml @@ -42,8 +42,5 @@ lazy_static = { version = "1.4.0", optional = true } [target.'cfg(crossbeam_loom)'.dependencies] loom = { version = "0.5", optional = true } -[build-dependencies] -autocfg = "1.0.0" - [dev-dependencies] rand = "0.8" diff --git a/crossbeam-utils/build.rs b/crossbeam-utils/build.rs index e7fabbd0c..9c924adeb 100644 --- a/crossbeam-utils/build.rs +++ b/crossbeam-utils/build.rs @@ -2,8 +2,6 @@ use std::env; -use autocfg::AutoCfg; - include!("no_atomic.rs"); // The rustc-cfg strings below are *not* public API. Please let us know by @@ -31,25 +29,12 @@ fn main() { } if NO_ATOMIC.contains(&&*target) { println!("cargo:rustc-cfg=crossbeam_no_atomic"); + println!("cargo:rustc-cfg=crossbeam_no_atomic_64"); + } else if NO_ATOMIC_64.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_64"); + } else { + // Otherwise, assuming `"max-atomic-width" == 64`. } - let cfg = match AutoCfg::new() { - Ok(cfg) => cfg, - Err(e) => { - println!( - "cargo:warning={}: unable to determine rustc version: {}", - env!("CARGO_PKG_NAME"), - e - ); - return; - } - }; - - 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"); - println!("cargo:rerun-if-changed=no_atomic.rs"); } diff --git a/crossbeam-utils/src/atomic/atomic_cell.rs b/crossbeam-utils/src/atomic/atomic_cell.rs index ad094b277..d911b9f4d 100644 --- a/crossbeam-utils/src/atomic/atomic_cell.rs +++ b/crossbeam-utils/src/atomic/atomic_cell.rs @@ -497,26 +497,19 @@ macro_rules! impl_arithmetic { }; } -#[cfg(has_atomic_u8)] impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); -#[cfg(all(has_atomic_u8, not(crossbeam_loom)))] 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(all(has_atomic_u16, not(crossbeam_loom)))] 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(all(has_atomic_u32, not(crossbeam_loom)))] impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); -#[cfg(all(has_atomic_u64, not(crossbeam_loom)))] +#[cfg(not(crossbeam_no_atomic_64))] impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); -#[cfg(all(has_atomic_u128, not(crossbeam_loom)))] -impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); -#[cfg(all(has_atomic_u128, not(crossbeam_loom)))] -impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); +// TODO: AtomicU128 is unstable +// impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); +// impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); impl_arithmetic!( usize, @@ -809,16 +802,13 @@ macro_rules! atomic { atomic!(@check, $t, AtomicUnit, $a, $atomic_op); atomic!(@check, $t, atomic::AtomicUsize, $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)] + #[cfg(not(crossbeam_no_atomic_64))] atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); - #[cfg(has_atomic_u128)] - atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op); + // TODO: AtomicU128 is unstable + // atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op); #[cfg(crossbeam_loom)] unimplemented!("loom does not support non-atomic atomic ops"); @@ -831,17 +821,15 @@ macro_rules! atomic { /// Returns `true` if operations on `AtomicCell` are lock-free. const fn atomic_is_lock_free() -> bool { // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36. - let is_lock_free = can_transmute::() | can_transmute::(); - #[cfg(has_atomic_u8)] - let is_lock_free = is_lock_free | can_transmute::(); - #[cfg(has_atomic_u16)] - let is_lock_free = is_lock_free | can_transmute::(); - #[cfg(has_atomic_u32)] - let is_lock_free = is_lock_free | can_transmute::(); - #[cfg(has_atomic_u64)] + let is_lock_free = can_transmute::() + | can_transmute::() + | can_transmute::() + | can_transmute::() + | can_transmute::(); + #[cfg(not(crossbeam_no_atomic_64))] let is_lock_free = is_lock_free | can_transmute::(); - #[cfg(has_atomic_u128)] - let is_lock_free = is_lock_free | can_transmute::(); + // TODO: AtomicU128 is unstable + // let is_lock_free = is_lock_free | can_transmute::(); is_lock_free } diff --git a/crossbeam-utils/src/atomic/consume.rs b/crossbeam-utils/src/atomic/consume.rs index f28e32bbf..277b370a5 100644 --- a/crossbeam-utils/src/atomic/consume.rs +++ b/crossbeam-utils/src/atomic/consume.rs @@ -68,21 +68,15 @@ macro_rules! impl_atomic { impl_atomic!(AtomicBool, bool); impl_atomic!(AtomicUsize, usize); impl_atomic!(AtomicIsize, isize); -#[cfg(has_atomic_u8)] impl_atomic!(AtomicU8, u8); -#[cfg(has_atomic_u8)] impl_atomic!(AtomicI8, i8); -#[cfg(has_atomic_u16)] impl_atomic!(AtomicU16, u16); -#[cfg(has_atomic_u16)] impl_atomic!(AtomicI16, i16); -#[cfg(has_atomic_u32)] impl_atomic!(AtomicU32, u32); -#[cfg(has_atomic_u32)] impl_atomic!(AtomicI32, i32); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_atomic!(AtomicU64, u64); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_atomic!(AtomicI64, i64); #[cfg(not(crossbeam_no_atomic))] diff --git a/crossbeam-utils/src/lib.rs b/crossbeam-utils/src/lib.rs index 6f9df04ae..a273e98ff 100644 --- a/crossbeam-utils/src/lib.rs +++ b/crossbeam-utils/src/lib.rs @@ -72,16 +72,12 @@ mod primitive { #[cfg(not(crossbeam_no_atomic))] pub(crate) use core::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; #[cfg(not(crossbeam_no_atomic))] - #[cfg(has_atomic_u16)] pub(crate) use core::sync::atomic::{AtomicI16, AtomicU16}; #[cfg(not(crossbeam_no_atomic))] - #[cfg(has_atomic_u32)] pub(crate) use core::sync::atomic::{AtomicI32, AtomicU32}; - #[cfg(not(crossbeam_no_atomic))] - #[cfg(has_atomic_u64)] + #[cfg(not(crossbeam_no_atomic_64))] pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64}; #[cfg(not(crossbeam_no_atomic))] - #[cfg(has_atomic_u8)] pub(crate) use core::sync::atomic::{AtomicI8, AtomicU8}; } diff --git a/crossbeam-utils/tests/atomic_cell.rs b/crossbeam-utils/tests/atomic_cell.rs index 3d91d81d6..65a3e86c3 100644 --- a/crossbeam-utils/tests/atomic_cell.rs +++ b/crossbeam-utils/tests/atomic_cell.rs @@ -9,17 +9,23 @@ fn is_lock_free() { 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!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); - 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!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); - assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u16)); + assert!(AtomicCell::::is_lock_free()); - assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u128)); + assert_eq!( + AtomicCell::::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) + ); + + // AtomicU128 is unstable + assert!(!AtomicCell::::is_lock_free()); } #[test] diff --git a/no_atomic.rs b/no_atomic.rs index 015a115ed..522b3b8ac 100644 --- a/no_atomic.rs +++ b/no_atomic.rs @@ -10,6 +10,47 @@ const NO_ATOMIC_CAS: &[&str] = &[ "thumbv6m-none-eabi", ]; #[allow(dead_code)] +const NO_ATOMIC_64: &[&str] = &[ + "arm-linux-androideabi", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv4t-unknown-linux-gnueabi", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv5te-unknown-linux-uclibceabi", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "hexagon-unknown-linux-musl", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips-unknown-linux-uclibc", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "mipsel-unknown-linux-uclibc", + "mipsel-unknown-none", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-linux-musl", + "powerpc-unknown-netbsd", + "powerpc-unknown-openbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "riscv32gc-unknown-linux-gnu", + "riscv32gc-unknown-linux-musl", + "riscv32imac-unknown-none-elf", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "thumbv8m.base-none-eabi", + "thumbv8m.main-none-eabi", + "thumbv8m.main-none-eabihf", + "mipsel-sony-psp", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", +]; +#[allow(dead_code)] const NO_ATOMIC: &[&str] = &[ "avr-unknown-gnu-atmega328", "msp430-none-elf",