From 4ab579f51eed138233d39d5ee30da0fb1c8aea69 Mon Sep 17 00:00:00 2001 From: Todd Joslin Date: Sun, 22 Dec 2024 17:25:07 -0500 Subject: [PATCH] Support non-atomic targets by using portable-atomic squashed commits from upstream #467 and rebased with updated deps --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ Cargo.toml | 5 +++++ ci/test-stable.sh | 7 +++++-- src/loom.rs | 3 +++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc868bbbc..512fe6460 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,6 +128,26 @@ jobs: cargo build --target ${{ matrix.target }} if: matrix.target == 'wasm32-unknown-unknown' + # Build for no_std environment. + no-std: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust + run: rustup update stable + - name: Install cargo-hack + run: cargo install cargo-hack + # thumbv7m-none-eabi supports atomic CAS. + # thumbv6m-none-eabi supports atomic, but not atomic CAS. + - run: rustup target add thumbv7m-none-eabi + - run: rustup target add thumbv6m-none-eabi + # * --optional-deps is needed for serde feature + # * --no-dev-deps is needed to avoid https://github.com/rust-lang/cargo/issues/4866 + - run: cargo hack build --target thumbv7m-none-eabi --feature-powerset --skip std,default --optional-deps --no-dev-deps + # A sound way to provide atomic CAS on platforms without native atomic CAS is system-dependent. + # portable-atomic provides major ways via cfgs and accepts user-defined implementations via critical-section feature. + - run: cargo hack build --target thumbv6m-none-eabi --feature-powerset --skip std,default --optional-deps --no-dev-deps --features extra-platforms,portable-atomic/critical-section + # Sanitizers tsan: name: tsan diff --git a/Cargo.toml b/Cargo.toml index ed385d197..7d822123b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,9 +21,14 @@ categories = ["network-programming", "data-structures"] [features] default = ["std"] std = [] +# Use portable-atomic crate to support platforms without atomic CAS. +# See https://docs.rs/portable-atomic for more information. +extra-platforms = ["portable-atomic"] [dependencies] serde = { version = "1.0.60", optional = true, default-features = false, features = ["alloc"] } +# Enable require-cas feature to provide a better error message if the end user forgets to use the cfg or feature. +portable-atomic = { version = "1.10", optional = true, default-features = false, features = ["require-cas"] } [dev-dependencies] serde_test = "1.0" diff --git a/ci/test-stable.sh b/ci/test-stable.sh index a8eaa3c65..ad9757449 100755 --- a/ci/test-stable.sh +++ b/ci/test-stable.sh @@ -16,7 +16,10 @@ if [[ "${RUST_VERSION}" == "nightly"* ]]; then cargo check --benches # Check minimal versions - cargo clean - cargo update -Zminimal-versions + # Remove dev-dependencies from Cargo.toml to prevent the next `cargo update` + # from determining minimal versions based on dev-dependencies. + cargo hack --remove-dev-deps --workspace + # Update Cargo.lock to minimal version dependencies. + cargo update -Z minimal-versions cargo check --all-features fi diff --git a/src/loom.rs b/src/loom.rs index 9e6b2d5e2..7d83b90ea 100644 --- a/src/loom.rs +++ b/src/loom.rs @@ -1,7 +1,10 @@ #[cfg(not(all(test, loom)))] pub(crate) mod sync { pub(crate) mod atomic { + #[cfg(not(feature = "extra-platforms"))] pub(crate) use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; + #[cfg(feature = "extra-platforms")] + pub(crate) use portable_atomic::{AtomicPtr, AtomicUsize, Ordering}; pub(crate) trait AtomicMut { fn with_mut(&mut self, f: F) -> R