| //@ check-pass |
| #![feature(const_atomic, const_raw_ptr_comparison)] |
| |
| use std::sync::atomic::*; |
| use std::sync::atomic::Ordering::*; |
| |
| const BOOL: () = { |
| let mut atomic: AtomicBool = AtomicBool::new(false); |
| |
| unsafe { |
| assert!(*atomic.get_mut() == false); |
| atomic.store(true, SeqCst); |
| assert!(*atomic.get_mut() == true); |
| atomic.fetch_or(false, SeqCst); |
| assert!(*atomic.get_mut() == true); |
| atomic.fetch_and(false, SeqCst); |
| assert!(*atomic.get_mut() == false); |
| atomic.fetch_nand(true, SeqCst); |
| assert!(*atomic.get_mut() == true); |
| atomic.fetch_xor(true, SeqCst); |
| assert!(*atomic.get_mut() == false); |
| } |
| }; |
| |
| const FENCES: () = { |
| fence(SeqCst); |
| fence(Release); |
| fence(Acquire); |
| fence(AcqRel); |
| compiler_fence(SeqCst); |
| compiler_fence(Release); |
| compiler_fence(Acquire); |
| compiler_fence(AcqRel); |
| }; |
| |
| const fn compare_result_u64(a: Result<u64, u64>, b: Result<u64, u64>) -> bool { |
| match (a, b) { |
| (Ok(a), Ok(b)) => a == b, |
| (Err(a), Err(b)) => a == b, |
| _ => false, |
| } |
| } |
| |
| #[cfg(target_has_atomic = "64")] |
| const ATOMIC_INT: () = { |
| let atomic = AtomicU64::new(0); |
| |
| atomic.store(1, SeqCst); |
| assert!(compare_result_u64(atomic.compare_exchange(0, 0x100, AcqRel, Acquire), Err(1))); |
| assert!(compare_result_u64(atomic.compare_exchange(0, 1, Release, Relaxed), Err(1))); |
| assert!(compare_result_u64(atomic.compare_exchange(1, 0, AcqRel, Relaxed), Ok(1))); |
| assert!(compare_result_u64(atomic.compare_exchange(0, 1, Relaxed, Relaxed), Ok(0))); |
| // compare_exchange_weak always succeeds when possible, but that is not a guarantee. |
| assert!(compare_result_u64(atomic.compare_exchange_weak(1, 0x100, AcqRel, Acquire), Ok(1))); |
| assert!(compare_result_u64(atomic.compare_exchange_weak(0, 2, Acquire, Relaxed), Err(0x100))); |
| assert!(compare_result_u64(atomic.compare_exchange_weak(0, 1, Release, Relaxed), Err(0x100))); |
| assert!(atomic.load(Relaxed) == 0x100); |
| |
| assert!(atomic.fetch_max(0x10, SeqCst) == 0x100); |
| assert!(atomic.fetch_max(0x100, SeqCst) == 0x100); |
| assert!(atomic.fetch_max(0x1000, SeqCst) == 0x100); |
| assert!(atomic.fetch_max(0x1000, SeqCst) == 0x1000); |
| assert!(atomic.fetch_max(0x2000, SeqCst) == 0x1000); |
| assert!(atomic.fetch_max(0x2000, SeqCst) == 0x2000); |
| |
| assert!(atomic.fetch_min(0x2000, SeqCst) == 0x2000); |
| assert!(atomic.fetch_min(0x2000, SeqCst) == 0x2000); |
| assert!(atomic.fetch_min(0x1000, SeqCst) == 0x2000); |
| assert!(atomic.fetch_min(0x1000, SeqCst) == 0x1000); |
| assert!(atomic.fetch_min(0x100, SeqCst) == 0x1000); |
| assert!(atomic.fetch_min(0x10, SeqCst) == 0x100); |
| |
| assert!(atomic.swap(1, SeqCst) == 0x10); |
| assert!(atomic.load(Relaxed) == 1); |
| |
| let atomic_signed = AtomicI64::new(0); |
| assert!(atomic_signed.fetch_min(-1, SeqCst) == 0); |
| assert!(atomic_signed.load(SeqCst) == -1); |
| assert!(atomic_signed.fetch_min(1, SeqCst) == -1); |
| assert!(atomic_signed.load(SeqCst) == -1); |
| assert!(atomic_signed.fetch_max(1, SeqCst) == -1); |
| assert!(atomic_signed.load(SeqCst) == 1); |
| assert!(atomic_signed.fetch_max(-1, SeqCst) == 1); |
| assert!(atomic_signed.load(SeqCst) == 1); |
| }; |
| |
| const ATOMIC_PTR: () = { |
| use std::ptr; |
| let array = [0i32; 4]; // a target to point to, to test provenance things |
| let x = array.as_ptr() as *mut i32; |
| |
| let ptr = AtomicPtr::<i32>::new(ptr::null_mut()); |
| assert!(ptr.load(Relaxed).guaranteed_eq(0 as *mut i32).unwrap()); |
| ptr.store(ptr::without_provenance_mut(13), SeqCst); |
| assert!(ptr.swap(x, Relaxed).guaranteed_eq(13 as *mut i32).unwrap()); |
| unsafe { assert!(ptr.load(Acquire).read() == 0) }; |
| }; |
| |
| fn main() {} |