From e0140d5d8bb4636cefc2f8c36d9a7ecbb6cc8770 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 20 Jan 2021 15:24:13 +0900 Subject: [PATCH] Support non-atomic targets Remove uses of unstable feature(cfg_target_has_atomic) fix setup codegen ci add comment update list Use portable-atomic and remove our own logic for now Adopt the third idea of https://github.com/tokio-rs/bytes/pull/573#issuecomment-1271567631. Enable portable-atomic's require-cas feature This provides a better error message if the end user forgets to use the cfg or feature. --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ Cargo.toml | 5 +++++ ci/test-stable.sh | 7 +++++-- src/buf/chain.rs | 4 ++-- src/buf/take.rs | 4 ++-- src/lib.rs | 1 + src/loom.rs | 3 +++ 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0658a142..5c747786f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,6 +118,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@v2 + - 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 793582af1..434073a6a 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.3", 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/buf/chain.rs b/src/buf/chain.rs index 97ac2eca5..c8bc36de9 100644 --- a/src/buf/chain.rs +++ b/src/buf/chain.rs @@ -1,5 +1,5 @@ use crate::buf::{IntoIter, UninitSlice}; -use crate::{Buf, BufMut, Bytes}; +use crate::{Buf, BufMut}; #[cfg(feature = "std")] use std::io::IoSlice; @@ -169,7 +169,7 @@ where n } - fn copy_to_bytes(&mut self, len: usize) -> Bytes { + fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes { let a_rem = self.a.remaining(); if a_rem >= len { self.a.copy_to_bytes(len) diff --git a/src/buf/take.rs b/src/buf/take.rs index a16a434ee..e74b064dd 100644 --- a/src/buf/take.rs +++ b/src/buf/take.rs @@ -1,4 +1,4 @@ -use crate::{Buf, Bytes}; +use crate::Buf; use core::cmp; @@ -145,7 +145,7 @@ impl Buf for Take { self.limit -= cnt; } - fn copy_to_bytes(&mut self, len: usize) -> Bytes { + fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes { assert!(len <= self.remaining(), "`len` greater than remaining"); let r = self.inner.copy_to_bytes(len); diff --git a/src/lib.rs b/src/lib.rs index 7ddd2205b..74b4ad846 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ ))] #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(bytes_unstable, feature(cfg_target_has_atomic))] //! Provides abstractions for working with bytes. //! 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