diff options
author | Joel Galenson <jgalenson@google.com> | 2021-06-22 10:09:30 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-06-22 10:09:30 +0000 |
commit | f61a55ceceaee70ab50328313126d1e3d1b62b55 (patch) | |
tree | c662582a391e8ddc05a36058307c9d9351ae136a | |
parent | 0a9d0cd11bb8f8dd61c4a5ec589da5ab9e2a875f (diff) | |
parent | 2ce91674eba239b60b91d77c02fe074e40ed8eda (diff) | |
download | crossbeam-utils-f61a55ceceaee70ab50328313126d1e3d1b62b55.tar.gz |
Upgrade rust/crates/crossbeam-utils to 0.8.5 am: 2ce91674eb
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/crossbeam-utils/+/1742398
Change-Id: I155201329f19e8637968f22131bd877fb9ff4353
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 27 | ||||
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | Cargo.toml.orig | 16 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | TEST_MAPPING | 6 | ||||
-rw-r--r-- | build.rs | 35 | ||||
-rw-r--r-- | no_atomic.rs | 59 | ||||
-rw-r--r-- | src/atomic/atomic_cell.rs | 79 | ||||
-rw-r--r-- | src/atomic/consume.rs | 24 | ||||
-rw-r--r-- | src/atomic/mod.rs | 8 | ||||
-rw-r--r-- | src/lib.rs | 27 | ||||
-rw-r--r-- | tests/atomic_cell.rs | 54 | ||||
-rw-r--r-- | tests/cache_padded.rs | 1 | ||||
-rw-r--r-- | tests/sharded_lock.rs | 2 |
16 files changed, 231 insertions, 126 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 78aaf0a..1f53d5d 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "d4f6785c9be365832eecfc04222f95a1c2dd314a" + "sha1": "6d4cdd4daf9a897deef6cde9569f2fbf12c29bc5" } } @@ -51,12 +51,6 @@ rust_defaults { "lazy_static", "std", ], - cfgs: [ - "has_atomic_u16", - "has_atomic_u32", - "has_atomic_u64", - "has_atomic_u8", - ], rustlibs: [ "libcfg_if", "liblazy_static", @@ -88,12 +82,6 @@ rust_defaults { "lazy_static", "std", ], - cfgs: [ - "has_atomic_u16", - "has_atomic_u32", - "has_atomic_u64", - "has_atomic_u8", - ], rustlibs: [ "libcfg_if", "libcrossbeam_utils", @@ -203,12 +191,6 @@ rust_library { "lazy_static", "std", ], - cfgs: [ - "has_atomic_u16", - "has_atomic_u32", - "has_atomic_u64", - "has_atomic_u8", - ], rustlibs: [ "libcfg_if", "liblazy_static", @@ -216,12 +198,11 @@ rust_library { } // dependent_library ["feature_list"] -// autocfg-1.0.1 // cfg-if-1.0.0 // getrandom-0.2.3 "std" // lazy_static-1.4.0 -// libc-0.2.94 +// libc-0.2.97 // ppv-lite86-0.2.10 "simd,std" -// rand-0.8.3 "alloc,default,getrandom,libc,rand_chacha,rand_hc,std,std_rng" -// rand_chacha-0.3.0 "std" -// rand_core-0.6.2 "alloc,getrandom,std" +// rand-0.8.4 "alloc,default,getrandom,libc,rand_chacha,rand_hc,std,std_rng" +// rand_chacha-0.3.1 "std" +// rand_core-0.6.3 "alloc,getrandom,std" diff --git a/CHANGELOG.md b/CHANGELOG.md index 1618732..8c485ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.8.5 + +- Add `AtomicCell::fetch_update` (#704) +- Support targets that do not have atomic CAS on stable Rust (#698) + # Version 0.8.4 - Bump `loom` dependency to version 0.5. (#686) @@ -13,7 +13,7 @@ [package] edition = "2018" name = "crossbeam-utils" -version = "0.8.4" +version = "0.8.5" authors = ["The Crossbeam Project Developers"] description = "Utilities for concurrent programming" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" @@ -30,8 +30,6 @@ version = "1.4.0" optional = true [dev-dependencies.rand] version = "0.8" -[build-dependencies.autocfg] -version = "1.0.0" [features] default = ["std"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 4962b71..16488cb 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -4,7 +4,7 @@ name = "crossbeam-utils" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-utils-X.Y.Z" git tag -version = "0.8.4" +version = "0.8.5" authors = ["The Crossbeam Project Developers"] edition = "2018" license = "MIT OR Apache-2.0" @@ -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,13 +37,10 @@ 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 } -[build-dependencies] -autocfg = "1.0.0" - [dev-dependencies] rand = "0.8" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/crossbeam-utils/crossbeam-utils-0.8.4.crate" + value: "https://static.crates.io/crates/crossbeam-utils/crossbeam-utils-0.8.5.crate" } - version: "0.8.4" + version: "0.8.5" license_type: NOTICE last_upgrade_date { year: 2021 - month: 5 - day: 20 + month: 6 + day: 21 } } diff --git a/TEST_MAPPING b/TEST_MAPPING index a68b776..eea3de0 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -27,6 +27,12 @@ }, { "name": "crossbeam-utils_device_test_tests_wait_group" + }, + { + "name": "unicode-xid_device_test_src_lib" + }, + { + "name": "unicode-xid_device_test_tests_exhaustive_tests" } ] } @@ -1,23 +1,40 @@ -use autocfg::AutoCfg; +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic.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 cfg = match AutoCfg::new() { - Ok(cfg) => cfg, + let target = match env::var("TARGET") { + Ok(target) => target, Err(e) => { println!( - "cargo:warning=crossbeam-utils: unable to determine rustc version: {}", + "cargo:warning={}: unable to get TARGET environment variable: {}", + 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"); + // 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.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + 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`. + } + + println!("cargo:rerun-if-changed=no_atomic.rs"); } diff --git a/no_atomic.rs b/no_atomic.rs new file mode 100644 index 0000000..522b3b8 --- /dev/null +++ b/no_atomic.rs @@ -0,0 +1,59 @@ +// This file is @generated by no_atomic.sh. +// It is not intended for manual editing. + +const NO_ATOMIC_CAS: &[&str] = &[ + "avr-unknown-gnu-atmega328", + "msp430-none-elf", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "thumbv4t-none-eabi", + "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", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", +]; diff --git a/src/atomic/atomic_cell.rs b/src/atomic/atomic_cell.rs index ad094b2..1a1c464 100644 --- a/src/atomic/atomic_cell.rs +++ b/src/atomic/atomic_cell.rs @@ -258,6 +258,40 @@ impl<T: Copy + Eq> AtomicCell<T> { pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> { unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) } } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else + /// `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been changed from other threads in + /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied + /// only once to the stored value. + /// + /// # Examples + /// + /// ```rust + /// use crossbeam_utils::atomic::AtomicCell; + /// + /// let a = AtomicCell::new(7); + /// assert_eq!(a.fetch_update(|_| None), Err(7)); + /// assert_eq!(a.fetch_update(|a| Some(a + 1)), Ok(7)); + /// assert_eq!(a.fetch_update(|a| Some(a + 1)), Ok(8)); + /// assert_eq!(a.load(), 9); + /// ``` + #[inline] + pub fn fetch_update<F>(&self, mut f: F) -> Result<T, T> + where + F: FnMut(T) -> Option<T>, + { + let mut prev = self.load(); + while let Some(next) = f(prev) { + match self.compare_exchange(prev, next) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } } macro_rules! impl_arithmetic { @@ -497,33 +531,25 @@ 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, atomic::AtomicUsize, "let a = AtomicCell::new(7usize);" ); -#[cfg(not(crossbeam_loom))] impl_arithmetic!( isize, atomic::AtomicIsize, @@ -809,16 +835,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 +854,15 @@ macro_rules! atomic { /// Returns `true` if operations on `AtomicCell<T>` are lock-free. const fn atomic_is_lock_free<T>() -> 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::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>(); - #[cfg(has_atomic_u8)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>(); - #[cfg(has_atomic_u16)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>(); - #[cfg(has_atomic_u32)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>(); - #[cfg(has_atomic_u64)] + let is_lock_free = can_transmute::<T, AtomicUnit>() + | can_transmute::<T, atomic::AtomicUsize>() + | can_transmute::<T, atomic::AtomicU8>() + | can_transmute::<T, atomic::AtomicU16>() + | can_transmute::<T, atomic::AtomicU32>(); + #[cfg(not(crossbeam_no_atomic_64))] let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>(); - #[cfg(has_atomic_u128)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>(); + // TODO: AtomicU128 is unstable + // let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>(); is_lock_free } diff --git a/src/atomic/consume.rs b/src/atomic/consume.rs index 0fbd93e..277b370 100644 --- a/src/atomic/consume.rs +++ b/src/atomic/consume.rs @@ -1,5 +1,6 @@ #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] use crate::primitive::sync::atomic::compiler_fence; +#[cfg(not(crossbeam_no_atomic))] use core::sync::atomic::Ordering; /// Trait which allows reading from primitive atomic types with "consume" ordering. @@ -25,6 +26,7 @@ pub trait AtomicConsume { fn load_consume(&self) -> Self::Val; } +#[cfg(not(crossbeam_no_atomic))] #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] macro_rules! impl_consume { () => { @@ -37,6 +39,7 @@ macro_rules! impl_consume { }; } +#[cfg(not(crossbeam_no_atomic))] #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] macro_rules! impl_consume { () => { @@ -49,12 +52,13 @@ macro_rules! impl_consume { macro_rules! impl_atomic { ($atomic:ident, $val:ty) => { - impl AtomicConsume for ::core::sync::atomic::$atomic { + #[cfg(not(crossbeam_no_atomic))] + impl AtomicConsume for core::sync::atomic::$atomic { type Val = $val; impl_consume!(); } #[cfg(crossbeam_loom)] - impl AtomicConsume for ::loom::sync::atomic::$atomic { + impl AtomicConsume for loom::sync::atomic::$atomic { type Val = $val; impl_consume!(); } @@ -63,32 +67,26 @@ macro_rules! impl_atomic { impl_atomic!(AtomicBool, bool); impl_atomic!(AtomicUsize, usize); -#[cfg(not(crossbeam_loom))] 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); -impl<T> AtomicConsume for ::core::sync::atomic::AtomicPtr<T> { +#[cfg(not(crossbeam_no_atomic))] +impl<T> AtomicConsume for core::sync::atomic::AtomicPtr<T> { type Val = *mut T; impl_consume!(); } #[cfg(crossbeam_loom)] -impl<T> AtomicConsume for ::loom::sync::atomic::AtomicPtr<T> { +impl<T> AtomicConsume for loom::sync::atomic::AtomicPtr<T> { type Val = *mut T; impl_consume!(); } diff --git a/src/atomic/mod.rs b/src/atomic/mod.rs index 874eaf2..fc713fc 100644 --- a/src/atomic/mod.rs +++ b/src/atomic/mod.rs @@ -3,11 +3,9 @@ //! * [`AtomicCell`], a thread-safe mutable memory location. //! * [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering. +#[cfg(not(crossbeam_no_atomic_cas))] #[cfg(not(crossbeam_loom))] -use cfg_if::cfg_if; - -#[cfg(not(crossbeam_loom))] -cfg_if! { +cfg_if::cfg_if! { // Use "wide" sequence lock if the pointer width <= 32 for preventing its counter against wrap // around. // @@ -25,8 +23,10 @@ cfg_if! { } } +#[cfg(not(crossbeam_no_atomic_cas))] mod atomic_cell; mod consume; +#[cfg(not(crossbeam_no_atomic_cas))] pub use self::atomic_cell::AtomicCell; pub use self::consume::AtomicConsume; @@ -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)] @@ -47,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,15 +70,13 @@ mod primitive { // use [`core::hint::spin_loop`] instead. #[allow(deprecated)] pub(crate) use core::sync::atomic::spin_loop_hint; - pub(crate) use core::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize}; - #[cfg(has_atomic_u16)] - pub(crate) use core::sync::atomic::{AtomicI16, AtomicU16}; - #[cfg(has_atomic_u32)] - pub(crate) use core::sync::atomic::{AtomicI32, AtomicU32}; - #[cfg(has_atomic_u64)] + #[cfg(not(crossbeam_no_atomic))] + 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(has_atomic_u8)] - pub(crate) use core::sync::atomic::{AtomicI8, AtomicU8}; } #[cfg(feature = "std")] @@ -86,15 +84,6 @@ mod primitive { } } -cfg_if! { - if #[cfg(feature = "alloc")] { - extern crate alloc; - } else if #[cfg(feature = "std")] { - extern crate std as alloc; - } -} - -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] pub mod atomic; mod cache_padded; diff --git a/tests/atomic_cell.rs b/tests/atomic_cell.rs index 3d91d81..28208ee 100644 --- a/tests/atomic_cell.rs +++ b/tests/atomic_cell.rs @@ -1,3 +1,4 @@ +use std::mem; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; @@ -8,18 +9,47 @@ fn is_lock_free() { struct UsizeWrap(usize); struct U8Wrap(bool); struct I16Wrap(i16); - - assert_eq!(AtomicCell::<usize>::is_lock_free(), true); - assert_eq!(AtomicCell::<isize>::is_lock_free(), true); - assert_eq!(AtomicCell::<UsizeWrap>::is_lock_free(), true); - - assert_eq!(AtomicCell::<u8>::is_lock_free(), cfg!(has_atomic_u8)); - assert_eq!(AtomicCell::<bool>::is_lock_free(), cfg!(has_atomic_u8)); - assert_eq!(AtomicCell::<U8Wrap>::is_lock_free(), cfg!(has_atomic_u8)); - - assert_eq!(AtomicCell::<I16Wrap>::is_lock_free(), cfg!(has_atomic_u16)); - - assert_eq!(AtomicCell::<u128>::is_lock_free(), cfg!(has_atomic_u128)); + #[repr(align(8))] + struct U64Align8(u64); + + assert!(AtomicCell::<usize>::is_lock_free()); + assert!(AtomicCell::<isize>::is_lock_free()); + assert!(AtomicCell::<UsizeWrap>::is_lock_free()); + + assert!(AtomicCell::<()>::is_lock_free()); + + assert!(AtomicCell::<u8>::is_lock_free()); + assert!(AtomicCell::<i8>::is_lock_free()); + assert!(AtomicCell::<bool>::is_lock_free()); + assert!(AtomicCell::<U8Wrap>::is_lock_free()); + + assert!(AtomicCell::<u16>::is_lock_free()); + assert!(AtomicCell::<i16>::is_lock_free()); + assert!(AtomicCell::<I16Wrap>::is_lock_free()); + + assert!(AtomicCell::<u32>::is_lock_free()); + assert!(AtomicCell::<i32>::is_lock_free()); + + // Sizes of both types must be equal, and the alignment of `u64` must be greater or equal than + // that of `AtomicU64`. In i686-unknown-linux-gnu, the alignment of `u64` is `4` and alignment + // of `AtomicU64` is `8`, so `AtomicCell<u64>` is not lock-free. + assert_eq!( + AtomicCell::<u64>::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) + && cfg!(any( + target_pointer_width = "64", + target_pointer_width = "128" + )) + ); + assert_eq!(mem::size_of::<U64Align8>(), 8); + assert_eq!(mem::align_of::<U64Align8>(), 8); + assert_eq!( + AtomicCell::<U64Align8>::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) + ); + + // AtomicU128 is unstable + assert!(!AtomicCell::<u128>::is_lock_free()); } #[test] diff --git a/tests/cache_padded.rs b/tests/cache_padded.rs index c9e7687..86e9a77 100644 --- a/tests/cache_padded.rs +++ b/tests/cache_padded.rs @@ -85,6 +85,7 @@ fn drops() { assert_eq!(count.get(), 2); } +#[allow(clippy::clone_on_copy)] // This is intentional. #[test] fn clone() { let a = CachePadded::new(17); diff --git a/tests/sharded_lock.rs b/tests/sharded_lock.rs index b4b8565..d999008 100644 --- a/tests/sharded_lock.rs +++ b/tests/sharded_lock.rs @@ -148,7 +148,7 @@ fn arc() { fn arc_access_in_unwind() { let arc = Arc::new(ShardedLock::new(1)); let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { + let _ = thread::spawn(move || { struct Unwinder { i: Arc<ShardedLock<isize>>, } |