From 466eddc4e9a5b59a3ca3ec422e05dd52aebd29c5 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 25 Jan 2025 21:05:35 +0900 Subject: [PATCH] Use cfg(target_has_atomic) on no-std targets to support platforms without atomic CAS --- .github/workflows/ci.yml | 17 +++++++++++++++++ README.md | 12 ++++++++++++ src/buf/buf_impl.rs | 2 ++ src/buf/chain.rs | 5 +++-- src/buf/take.rs | 5 +++-- src/lib.rs | 9 +++++++++ 6 files changed, 46 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc868bbbc..e68048e2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,6 +128,23 @@ 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 + uses: taiki-e/install-action@cargo-hack + # thumbv6m-none-eabi supports atomic, but not atomic CAS. + # thumbv7m-none-eabi supports atomic CAS. + - run: rustup target add thumbv6m-none-eabi thumbv7m-none-eabi + # * --optional-deps is needed for serde feature + # * --no-dev-deps is needed to avoid https://github.com/rust-lang/cargo/issues/4866 + # Note that Bytes and BytesMut are provided only on platforms that supports atomic CAS. + - run: cargo hack build --target thumbv6m-none-eabi --target thumbv7m-none-eabi --feature-powerset --skip std,default --optional-deps --no-dev-deps + # Sanitizers tsan: name: tsan diff --git a/README.md b/README.md index be46642a4..dba52e2b2 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,18 @@ Next, add this to your crate: use bytes::{Bytes, BytesMut, Buf, BufMut}; ``` +## no_std support + +To use `bytes` with no_std environment, disable the (enabled by default) `std` feature. + +```toml +[dependencies] +bytes = { version = "1", default-features = false } +``` + +On no_std environment without atomic CAS, such as thumbv6m, `Bytes` and `BytesMut` are currently not provided. +See [#467](https://github.com/tokio-rs/bytes/pull/467) for the proposal about support these types on such a environment. + ## Serde support Serde support is optional and disabled by default. To enable use the feature `serde`. diff --git a/src/buf/buf_impl.rs b/src/buf/buf_impl.rs index 192034fbe..697167c38 100644 --- a/src/buf/buf_impl.rs +++ b/src/buf/buf_impl.rs @@ -2355,6 +2355,7 @@ pub trait Buf { /// # Panics /// /// This function panics if `len > self.remaining()`. + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes { use super::BufMut; @@ -2872,6 +2873,7 @@ macro_rules! deref_forward_buf { } #[inline] + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes { (**self).copy_to_bytes(len) } diff --git a/src/buf/chain.rs b/src/buf/chain.rs index 97ac2eca5..a58fc949e 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,8 @@ where n } - fn copy_to_bytes(&mut self, len: usize) -> Bytes { + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + 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 fc4e39dda..c4b56d9df 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; @@ -148,7 +148,8 @@ impl Buf for Take { self.limit -= cnt; } - fn copy_to_bytes(&mut self, len: usize) -> Bytes { + #[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] + 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 cfc828130..3388930a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,17 +80,25 @@ extern crate std; pub mod buf; pub use crate::buf::{Buf, BufMut}; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] mod bytes; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] mod bytes_mut; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] mod fmt; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] mod loom; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] pub use crate::bytes::Bytes; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] pub use crate::bytes_mut::BytesMut; // Optional Serde support #[cfg(feature = "serde")] +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] mod serde; +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[inline(never)] #[cold] fn abort() -> ! { @@ -194,6 +202,7 @@ fn panic_does_not_fit(size: usize, nbytes: usize) -> ! { /// /// But due to min rust is 1.39 and it is only stabilized /// in 1.47, we cannot use it. +#[cfg_attr(target_os = "none", cfg(target_has_atomic = "ptr"))] #[inline] fn offset_from(dst: *const u8, original: *const u8) -> usize { dst as usize - original as usize