blob: c8501851653d075140b029ab5336b0c9a5d32cd3 [file]
//@ 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() {}