diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 724d858a3..0051f5f5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,6 +86,19 @@ jobs: - name: dependency tree check run: ./ci/dependencies.sh + # When this job failed, run ci/no_atomic_cas.sh and commit result changes. + # TODO(taiki-e): Ideally, this should be automated using a bot that creates + # PR when failed, but there is no bandwidth to implement it + # right now... + codegen: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Install Rust + run: rustup update nightly && rustup default nightly + - run: ci/no_atomic_cas.sh + - run: git diff --exit-code + # Check formatting. rustfmt: name: rustfmt @@ -93,7 +106,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Rust - run: rustup update stable && rustup default stable + run: rustup update stable - name: rustfmt run: ./ci/rustfmt.sh @@ -104,7 +117,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Rust - run: rustup update stable && rustup default stable + run: rustup update stable - name: clippy run: ./ci/clippy.sh @@ -126,7 +139,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Rust - run: rustup update stable && rustup default stable + run: rustup update stable - name: loom run: ./ci/crossbeam-epoch-loom.sh @@ -154,6 +167,7 @@ jobs: - test - features - dependencies + - codegen - rustfmt - clippy - san diff --git a/Cargo.toml b/Cargo.toml index 4389b7931..1a490e5ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,8 +36,9 @@ alloc = ["crossbeam-epoch/alloc", "crossbeam-queue/alloc"] # Enable to use of unstable functionality. # This is disabled by default and requires recent nightly compiler. -# Note that this is outside of the normal semver guarantees and minor versions -# of crossbeam may make breaking changes to them at any time. +# +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. nightly = ["crossbeam-epoch/nightly", "crossbeam-utils/nightly", "crossbeam-queue/nightly"] [dependencies] diff --git a/build.rs b/build.rs new file mode 100644 index 000000000..ad7715cf1 --- /dev/null +++ b/build.rs @@ -0,0 +1,32 @@ +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic_cas.rs"); + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let target = match env::var("TARGET") { + Ok(target) => target, + Err(e) => { + println!( + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_*`, not `has_*`. This allows treating + // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't + // run. This is needed for compatibility with non-cargo build systems that + // don't run the build script. + if NO_ATOMIC_CAS_TARGETS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + + println!("cargo:rerun-if-changed=no_atomic_cas.rs"); +} diff --git a/ci/check-features.sh b/ci/check-features.sh index 1eeddc520..c6901d0b7 100755 --- a/ci/check-features.sh +++ b/ci/check-features.sh @@ -22,7 +22,5 @@ else rustup target add thumbv7m-none-eabi rustup target add thumbv6m-none-eabi cargo hack check --all --feature-powerset --no-dev-deps --exclude benchmarks --target thumbv7m-none-eabi --skip std,default - # * `--features nightly` is required for enable `cfg_target_has_atomic`. - # * `--ignore-unknown-features` - some crates doesn't have 'nightly' feature - cargo hack check --all --feature-powerset --no-dev-deps --exclude benchmarks --target thumbv6m-none-eabi --skip std,default --features nightly --ignore-unknown-features + cargo hack check --all --feature-powerset --no-dev-deps --exclude benchmarks --target thumbv6m-none-eabi --skip std,default fi diff --git a/ci/no_atomic_cas.sh b/ci/no_atomic_cas.sh new file mode 100755 index 000000000..40b2f1b90 --- /dev/null +++ b/ci/no_atomic_cas.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Update the list of targets that do not support atomic CAS operations. +# +# Usage: +# ./ci/no_atomic_cas.sh + +set -euo pipefail +IFS=$'\n\t' + +cd "$(cd "$(dirname "$0")" && pwd)"/.. + +file="no_atomic_cas.rs" + +{ + echo "// This file is @generated by $(basename "$0")." + echo "// It is not intended for manual editing." + echo "" + echo "const NO_ATOMIC_CAS_TARGETS: &[&str] = &[" +} >"$file" + +for target in $(rustc --print target-list); do + res=$(rustc --print target-spec-json -Z unstable-options --target "$target" \ + | jq -r "select(.\"atomic-cas\" == false)") + [[ -z "$res" ]] || echo " \"$target\"," >>"$file" +done + +echo "];" >>"$file" diff --git a/crossbeam-channel/Cargo.toml b/crossbeam-channel/Cargo.toml index 0e048a262..c2812fef4 100644 --- a/crossbeam-channel/Cargo.toml +++ b/crossbeam-channel/Cargo.toml @@ -20,6 +20,8 @@ default = ["std"] # Enable to use APIs that require `std`. # This is enabled by default. +# +# NOTE: Disabling `std` feature is not supported yet. std = ["crossbeam-utils/std"] [dependencies] diff --git a/crossbeam-deque/Cargo.toml b/crossbeam-deque/Cargo.toml index 55e22351b..cba710e74 100644 --- a/crossbeam-deque/Cargo.toml +++ b/crossbeam-deque/Cargo.toml @@ -20,6 +20,8 @@ default = ["std"] # Enable to use APIs that require `std`. # This is enabled by default. +# +# NOTE: Disabling `std` feature is not supported yet. std = ["crossbeam-epoch/std", "crossbeam-utils/std"] [dependencies] diff --git a/crossbeam-epoch/Cargo.toml b/crossbeam-epoch/Cargo.toml index de70ebb87..18154259b 100644 --- a/crossbeam-epoch/Cargo.toml +++ b/crossbeam-epoch/Cargo.toml @@ -24,18 +24,21 @@ std = ["alloc", "crossbeam-utils/std", "lazy_static"] # Enable to use APIs that require `alloc`. # This is enabled by default and also enabled if the `std` feature is enabled. +# +# NOTE: Disabling both `std` *and* `alloc` features is not supported yet. alloc = [] # Enable to use of unstable functionality. # This is disabled by default and requires recent nightly compiler. -# Note that this is outside of the normal semver guarantees and minor versions -# of crossbeam may make breaking changes to them at any time. +# +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. nightly = ["crossbeam-utils/nightly", "const_fn"] # Enable the use of loom for concurrency testing. # -# This configuration option is outside of the normal semver guarantees: minor -# versions of crossbeam may make breaking changes to it at any time. +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. loom = ["loom-crate", "crossbeam-utils/loom"] [dependencies] @@ -45,8 +48,8 @@ memoffset = "0.6" # Enable the use of loom for concurrency testing. # -# This configuration option is outside of the normal semver guarantees: minor -# versions of crossbeam may make breaking changes to it at any time. +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. [target.'cfg(crossbeam_loom)'.dependencies] loom-crate = { package = "loom", version = "0.5", optional = true } diff --git a/crossbeam-epoch/build.rs b/crossbeam-epoch/build.rs new file mode 100644 index 000000000..ad7715cf1 --- /dev/null +++ b/crossbeam-epoch/build.rs @@ -0,0 +1,32 @@ +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic_cas.rs"); + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let target = match env::var("TARGET") { + Ok(target) => target, + Err(e) => { + println!( + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_*`, not `has_*`. This allows treating + // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't + // run. This is needed for compatibility with non-cargo build systems that + // don't run the build script. + if NO_ATOMIC_CAS_TARGETS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + + println!("cargo:rerun-if-changed=no_atomic_cas.rs"); +} diff --git a/crossbeam-epoch/no_atomic_cas.rs b/crossbeam-epoch/no_atomic_cas.rs new file mode 120000 index 000000000..3d7380fad --- /dev/null +++ b/crossbeam-epoch/no_atomic_cas.rs @@ -0,0 +1 @@ +../no_atomic_cas.rs \ No newline at end of file diff --git a/crossbeam-epoch/src/lib.rs b/crossbeam-epoch/src/lib.rs index 81b6b37c9..8dfd5104a 100644 --- a/crossbeam-epoch/src/lib.rs +++ b/crossbeam-epoch/src/lib.rs @@ -62,7 +62,6 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] #![cfg_attr(feature = "nightly", feature(const_fn_trait_bound))] #[cfg(crossbeam_loom)] @@ -143,7 +142,7 @@ mod primitive { pub(crate) use core::sync::atomic::fence; pub(crate) use core::sync::atomic::AtomicUsize; } - #[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] + #[cfg(not(crossbeam_no_atomic_cas))] pub(crate) use alloc::sync::Arc; } @@ -154,7 +153,7 @@ mod primitive { pub(crate) use lazy_static::lazy_static; } -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(not(crossbeam_no_atomic_cas))] cfg_if! { if #[cfg(feature = "alloc")] { extern crate alloc; diff --git a/crossbeam-queue/Cargo.toml b/crossbeam-queue/Cargo.toml index 622536eb8..b79778d83 100644 --- a/crossbeam-queue/Cargo.toml +++ b/crossbeam-queue/Cargo.toml @@ -24,12 +24,17 @@ std = ["alloc", "crossbeam-utils/std"] # Enable to use APIs that require `alloc`. # This is enabled by default and also enabled if the `std` feature is enabled. +# +# NOTE: Disabling both `std` *and* `alloc` features is not supported yet. alloc = [] +# These features are no longer used. +# TODO: remove in the next major version. # Enable to use of unstable functionality. # This is disabled by default and requires recent nightly compiler. -# Note that this is outside of the normal semver guarantees and minor versions -# of crossbeam may make breaking changes to them at any time. +# +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. nightly = ["crossbeam-utils/nightly"] [dependencies] diff --git a/crossbeam-queue/build.rs b/crossbeam-queue/build.rs new file mode 100644 index 000000000..ad7715cf1 --- /dev/null +++ b/crossbeam-queue/build.rs @@ -0,0 +1,32 @@ +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic_cas.rs"); + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let target = match env::var("TARGET") { + Ok(target) => target, + Err(e) => { + println!( + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_*`, not `has_*`. This allows treating + // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't + // run. This is needed for compatibility with non-cargo build systems that + // don't run the build script. + if NO_ATOMIC_CAS_TARGETS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + + println!("cargo:rerun-if-changed=no_atomic_cas.rs"); +} diff --git a/crossbeam-queue/no_atomic_cas.rs b/crossbeam-queue/no_atomic_cas.rs new file mode 120000 index 000000000..3d7380fad --- /dev/null +++ b/crossbeam-queue/no_atomic_cas.rs @@ -0,0 +1 @@ +../no_atomic_cas.rs \ No newline at end of file diff --git a/crossbeam-queue/src/lib.rs b/crossbeam-queue/src/lib.rs index cba6416f6..846d7c2e1 100644 --- a/crossbeam-queue/src/lib.rs +++ b/crossbeam-queue/src/lib.rs @@ -19,9 +19,8 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(not(crossbeam_no_atomic_cas))] cfg_if::cfg_if! { if #[cfg(feature = "alloc")] { extern crate alloc; diff --git a/crossbeam-skiplist/Cargo.toml b/crossbeam-skiplist/Cargo.toml index f6c46efaa..beae558d9 100644 --- a/crossbeam-skiplist/Cargo.toml +++ b/crossbeam-skiplist/Cargo.toml @@ -24,14 +24,10 @@ std = ["alloc", "crossbeam-epoch/std", "crossbeam-utils/std"] # Enable to use APIs that require `alloc`. # This is enabled by default and also enabled if the `std` feature is enabled. +# +# NOTE: Disabling both `std` *and* `alloc` features is not supported yet. alloc = ["crossbeam-epoch/alloc"] -# Enable to use of unstable functionality. -# This is disabled by default and requires recent nightly compiler. -# Note that this is outside of the normal semver guarantees and minor versions -# of crossbeam may make breaking changes to them at any time. -nightly = ["crossbeam-epoch/nightly", "crossbeam-utils/nightly"] - [dependencies] cfg-if = "1" diff --git a/crossbeam-skiplist/build.rs b/crossbeam-skiplist/build.rs new file mode 100644 index 000000000..ad7715cf1 --- /dev/null +++ b/crossbeam-skiplist/build.rs @@ -0,0 +1,32 @@ +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic_cas.rs"); + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let target = match env::var("TARGET") { + Ok(target) => target, + Err(e) => { + println!( + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_*`, not `has_*`. This allows treating + // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't + // run. This is needed for compatibility with non-cargo build systems that + // don't run the build script. + if NO_ATOMIC_CAS_TARGETS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + + println!("cargo:rerun-if-changed=no_atomic_cas.rs"); +} diff --git a/crossbeam-skiplist/no_atomic_cas.rs b/crossbeam-skiplist/no_atomic_cas.rs new file mode 120000 index 000000000..3d7380fad --- /dev/null +++ b/crossbeam-skiplist/no_atomic_cas.rs @@ -0,0 +1 @@ +../no_atomic_cas.rs \ No newline at end of file diff --git a/crossbeam-skiplist/src/lib.rs b/crossbeam-skiplist/src/lib.rs index 13988fa32..cb5f0462d 100644 --- a/crossbeam-skiplist/src/lib.rs +++ b/crossbeam-skiplist/src/lib.rs @@ -242,11 +242,10 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] use cfg_if::cfg_if; -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(not(crossbeam_no_atomic_cas))] cfg_if! { if #[cfg(feature = "alloc")] { extern crate alloc; diff --git a/crossbeam-utils/Cargo.toml b/crossbeam-utils/Cargo.toml index 4962b7141..212671e59 100644 --- a/crossbeam-utils/Cargo.toml +++ b/crossbeam-utils/Cargo.toml @@ -22,10 +22,13 @@ default = ["std"] # This is enabled by default. std = ["lazy_static"] +# These features are no longer used. +# TODO: remove in the next major version. # Enable to use of unstable functionality. # This is disabled by default and requires recent nightly compiler. -# Note that this is outside of the normal semver guarantees and minor versions -# of crossbeam may make breaking changes to them at any time. +# +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. nightly = [] [dependencies] @@ -34,8 +37,8 @@ lazy_static = { version = "1.4.0", optional = true } # Enable the use of loom for concurrency testing. # -# This configuration option is outside of the normal semver guarantees: minor -# versions of crossbeam may make breaking changes to it at any time. +# NOTE: This feature is outside of the normal semver guarantees and minor or +# patch versions of crossbeam may make breaking changes to them at any time. [target.'cfg(crossbeam_loom)'.dependencies] loom = { version = "0.5", optional = true } diff --git a/crossbeam-utils/build.rs b/crossbeam-utils/build.rs index 3e5102183..a2d5d2b86 100644 --- a/crossbeam-utils/build.rs +++ b/crossbeam-utils/build.rs @@ -1,9 +1,35 @@ +#![warn(rust_2018_idioms)] + +use std::env; + use autocfg::AutoCfg; +include!("no_atomic_cas.rs"); + // The rustc-cfg strings below are *not* public API. Please let us know by // opening a GitHub issue if your build environment requires some way to enable // these cfgs other than by executing our build script. fn main() { + let target = match env::var("TARGET") { + Ok(target) => target, + Err(e) => { + println!( + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_*`, not `has_*`. This allows treating + // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't + // run. This is needed for compatibility with non-cargo build systems that + // don't run the build script. + if NO_ATOMIC_CAS_TARGETS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + let cfg = match AutoCfg::new() { Ok(cfg) => cfg, Err(e) => { diff --git a/crossbeam-utils/no_atomic_cas.rs b/crossbeam-utils/no_atomic_cas.rs new file mode 120000 index 000000000..3d7380fad --- /dev/null +++ b/crossbeam-utils/no_atomic_cas.rs @@ -0,0 +1 @@ +../no_atomic_cas.rs \ No newline at end of file diff --git a/crossbeam-utils/src/lib.rs b/crossbeam-utils/src/lib.rs index 880d37ec6..a533af257 100644 --- a/crossbeam-utils/src/lib.rs +++ b/crossbeam-utils/src/lib.rs @@ -38,7 +38,6 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] #[cfg(crossbeam_loom)] #[allow(unused_imports)] @@ -94,7 +93,7 @@ cfg_if! { } } -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(not(crossbeam_no_atomic_cas))] pub mod atomic; mod cache_padded; diff --git a/no_atomic_cas.rs b/no_atomic_cas.rs new file mode 100644 index 000000000..0819af1a4 --- /dev/null +++ b/no_atomic_cas.rs @@ -0,0 +1,11 @@ +// This file is @generated by no_atomic_cas.sh. +// It is not intended for manual editing. + +const NO_ATOMIC_CAS_TARGETS: &[&str] = &[ + "avr-unknown-gnu-atmega328", + "msp430-none-elf", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", +]; diff --git a/src/lib.rs b/src/lib.rs index 9d7d37416..6fbf4a051 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,9 +52,8 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(not(crossbeam_no_atomic_cas))] pub use crossbeam_utils::atomic; pub mod utils {