diff options
Diffstat (limited to 'tests/atomic_cell.rs')
-rw-r--r-- | tests/atomic_cell.rs | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/tests/atomic_cell.rs b/tests/atomic_cell.rs index da7a6e1..edb7a4b 100644 --- a/tests/atomic_cell.rs +++ b/tests/atomic_cell.rs @@ -35,11 +35,7 @@ fn is_lock_free() { // 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" - )) + cfg!(not(crossbeam_no_atomic_64)) && std::mem::align_of::<u64>() == 8 ); assert_eq!(mem::size_of::<U64Align8>(), 8); assert_eq!(mem::align_of::<U64Align8>(), 8); @@ -330,3 +326,51 @@ fn issue_748() { let x = AtomicCell::new(Test::FieldLess); assert_eq!(x.load(), Test::FieldLess); } + +// https://github.com/crossbeam-rs/crossbeam/issues/833 +#[rustversion::since(1.40)] // const_constructor requires Rust 1.40 +#[test] +fn issue_833() { + use std::num::NonZeroU128; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::thread; + + #[cfg(miri)] + const N: usize = 10_000; + #[cfg(not(miri))] + const N: usize = 1_000_000; + + #[allow(dead_code)] + enum Enum { + NeverConstructed, + Cell(AtomicCell<NonZeroU128>), + } + + static STATIC: Enum = Enum::Cell(AtomicCell::new(match NonZeroU128::new(1) { + Some(nonzero) => nonzero, + None => unreachable!(), + })); + static FINISHED: AtomicBool = AtomicBool::new(false); + + let handle = thread::spawn(|| { + let cell = match &STATIC { + Enum::NeverConstructed => unreachable!(), + Enum::Cell(cell) => cell, + }; + let x = NonZeroU128::new(0xFFFF_FFFF_FFFF_FFFF_0000_0000_0000_0000).unwrap(); + let y = NonZeroU128::new(0x0000_0000_0000_0000_FFFF_FFFF_FFFF_FFFF).unwrap(); + while !FINISHED.load(Ordering::Relaxed) { + cell.store(x); + cell.store(y); + } + }); + + for _ in 0..N { + if let Enum::NeverConstructed = STATIC { + unreachable!(":("); + } + } + + FINISHED.store(true, Ordering::Relaxed); + handle.join().unwrap(); +} |