From debc1016e018841f7b654caa4011e88bc651f778 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 27 May 2021 21:28:17 +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. --- .github/workflows/ci.yml | 4 ++- ci/no_atomic.sh | 25 +++++++++++++ ci/test.sh | 6 ++-- 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 | 20 ++++------- crossbeam-utils/tests/atomic_cell.rs | 28 ++++++++++----- no_atomic.rs | 41 +++++++++++++++++++++ 10 files changed, 122 insertions(+), 84 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7c312d3d..d54f26b8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,9 @@ jobs: name: test env: RUST_VERSION: ${{ matrix.rust }} - TARGET: ${{ matrix.target }} + RUST_TARGET: ${{ matrix.target }} strategy: + fail-fast: false matrix: include: - rust: 1.36.0 @@ -63,6 +64,7 @@ jobs: env: RUST_VERSION: ${{ matrix.rust }} strategy: + fail-fast: false matrix: rust: - 1.36.0 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/ci/test.sh b/ci/test.sh index c0c633d30..5bda4ff05 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -5,10 +5,10 @@ set -ex export RUSTFLAGS="-D warnings" -if [[ -n "$TARGET" ]]; then - # If TARGET is specified, use cross for testing. +if [[ -n "$RUST_TARGET" ]]; then + # If RUST_TARGET is specified, use cross for testing. cargo install cross - cross test --all --target "$TARGET" --exclude benchmarks -- --test-threads=1 + cross test --all --target "$RUST_TARGET" --exclude benchmarks -- --test-threads=1 # For now, the non-host target only runs tests. exit 0 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..191c5a17d 100644 --- a/crossbeam-utils/src/lib.rs +++ b/crossbeam-utils/src/lib.rs @@ -46,7 +46,8 @@ mod primitive { pub(crate) mod atomic { pub(crate) use loom::sync::atomic::spin_loop_hint; pub(crate) use loom::sync::atomic::{ - AtomicBool, AtomicU16, AtomicU32, AtomicU64, AtomicU8, AtomicUsize, + AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, + AtomicU32, AtomicU64, AtomicU8, AtomicUsize, }; // FIXME: loom does not support compiler_fence at the moment. @@ -70,19 +71,12 @@ mod primitive { #[allow(deprecated)] pub(crate) use core::sync::atomic::spin_loop_hint; #[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)] + pub(crate) use core::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, + AtomicU8, AtomicUsize, + }; + #[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}; } #[cfg(feature = "std")] diff --git a/crossbeam-utils/tests/atomic_cell.rs b/crossbeam-utils/tests/atomic_cell.rs index 3d91d81d6..087950a0f 100644 --- a/crossbeam-utils/tests/atomic_cell.rs +++ b/crossbeam-utils/tests/atomic_cell.rs @@ -9,17 +9,29 @@ 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!(AtomicCell::::is_lock_free()); - assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u16)); + assert!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); - assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u128)); + assert!(AtomicCell::::is_lock_free()); + assert!(AtomicCell::::is_lock_free()); + + assert_eq!( + AtomicCell::::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) && cfg!(target_pointer_width = "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",