diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 69cfd0368d635..ccd1ffa8497a7 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -53,19 +53,35 @@ extern "rust-intrinsic" { // NB: These intrinsics take raw pointers because they mutate aliased // memory, which is not valid for either `&` or `&mut`. + #[cfg(stage0)] pub fn atomic_cxchg(dst: *mut T, old: T, src: T) -> T; + #[cfg(stage0)] pub fn atomic_cxchg_acq(dst: *mut T, old: T, src: T) -> T; + #[cfg(stage0)] pub fn atomic_cxchg_rel(dst: *mut T, old: T, src: T) -> T; + #[cfg(stage0)] pub fn atomic_cxchg_acqrel(dst: *mut T, old: T, src: T) -> T; + #[cfg(stage0)] pub fn atomic_cxchg_relaxed(dst: *mut T, old: T, src: T) -> T; + + #[cfg(not(stage0))] + pub fn atomic_cxchg(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(not(stage0))] + pub fn atomic_cxchg_acq(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(not(stage0))] + pub fn atomic_cxchg_rel(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(not(stage0))] + pub fn atomic_cxchg_acqrel(dst: *mut T, old: T, src: T) -> (T, bool); + #[cfg(not(stage0))] + pub fn atomic_cxchg_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); #[cfg(not(stage0))] - pub fn atomic_cxchg_failrelaxed(dst: *mut T, old: T, src: T) -> T; + pub fn atomic_cxchg_failrelaxed(dst: *mut T, old: T, src: T) -> (T, bool); #[cfg(not(stage0))] - pub fn atomic_cxchg_failacq(dst: *mut T, old: T, src: T) -> T; + pub fn atomic_cxchg_failacq(dst: *mut T, old: T, src: T) -> (T, bool); #[cfg(not(stage0))] - pub fn atomic_cxchg_acq_failrelaxed(dst: *mut T, old: T, src: T) -> T; + pub fn atomic_cxchg_acq_failrelaxed(dst: *mut T, old: T, src: T) -> (T, bool); #[cfg(not(stage0))] - pub fn atomic_cxchg_acqrel_failrelaxed(dst: *mut T, old: T, src: T) -> T; + pub fn atomic_cxchg_acqrel_failrelaxed(dst: *mut T, old: T, src: T) -> (T, bool); #[cfg(not(stage0))] pub fn atomic_cxchgweak(dst: *mut T, old: T, src: T) -> (T, bool); diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 0c831bff763d0..40555481fc0d8 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -77,6 +77,8 @@ use marker::{Send, Sync}; use intrinsics; use cell::UnsafeCell; +use result::Result::{self, Ok, Err}; + use default::Default; use fmt; @@ -311,13 +313,16 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { - self.compare_exchange(current, new, order, strongest_failure_ordering(order)) + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } } /// Stores a value into the `bool` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `current`, then the value - /// was updated. + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. /// /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this /// operation. The first describes the required ordering if the operation succeeds while the @@ -336,13 +341,13 @@ impl AtomicBool { /// false, /// Ordering::Acquire, /// Ordering::Relaxed), - /// true); + /// Ok(true)); /// assert_eq!(some_bool.load(Ordering::Relaxed), false); /// /// assert_eq!(some_bool.compare_exchange(true, true, /// Ordering::SeqCst, /// Ordering::Acquire), - /// false); + /// Err(false)); /// assert_eq!(some_bool.load(Ordering::Relaxed), false); /// ``` #[inline] @@ -351,19 +356,22 @@ impl AtomicBool { current: bool, new: bool, success: Ordering, - failure: Ordering) -> bool { + failure: Ordering) -> Result { let current = if current { UINT_TRUE } else { 0 }; let new = if new { UINT_TRUE } else { 0 }; - unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) > 0 } + match unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } { + Ok(x) => Ok(x > 0), + Err(x) => Err(x > 0), + } } /// Stores a value into the `bool` if the current value is the same as the `current` value. /// /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the /// comparison succeeds, which can result in more efficient code on some platforms. The - /// returned value is a tuple of the existing value and a flag indicating whether the - /// new value was written. + /// return value is a result indicating whether the new value was written and containing the + /// previous value. /// /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory /// ordering of this operation. The first describes the required ordering if the operation @@ -382,13 +390,9 @@ impl AtomicBool { /// let new = true; /// let mut old = val.load(Ordering::Relaxed); /// loop { - /// let result = val.compare_exchange_weak(old, new, - /// Ordering::SeqCst, - /// Ordering::Relaxed); - /// if result.1 { - /// break; - /// } else { - /// old = result.0; + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, /// } /// } /// ``` @@ -398,14 +402,15 @@ impl AtomicBool { current: bool, new: bool, success: Ordering, - failure: Ordering) -> (bool, bool) { + failure: Ordering) -> Result { let current = if current { UINT_TRUE } else { 0 }; let new = if new { UINT_TRUE } else { 0 }; - let result = unsafe { - atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) - }; - (result.0 > 0, result.1) + match unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, + success, failure) } { + Ok(x) => Ok(x > 0), + Err(x) => Err(x > 0), + } } /// Logical "and" with a boolean value. @@ -644,13 +649,16 @@ impl AtomicIsize { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn compare_and_swap(&self, current: isize, new: isize, order: Ordering) -> isize { - self.compare_exchange(current, new, order, strongest_failure_ordering(order)) + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } } /// Stores a value into the `isize` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `current`, then the value - /// was updated. + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. /// /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this /// operation. The first describes the required ordering if the operation succeeds while the @@ -668,13 +676,13 @@ impl AtomicIsize { /// assert_eq!(some_isize.compare_exchange(5, 10, /// Ordering::Acquire, /// Ordering::Relaxed), - /// 5); + /// Ok(5)); /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); /// /// assert_eq!(some_isize.compare_exchange(6, 12, /// Ordering::SeqCst, /// Ordering::Acquire), - /// 10); + /// Err(10)); /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); /// ``` #[inline] @@ -683,7 +691,7 @@ impl AtomicIsize { current: isize, new: isize, success: Ordering, - failure: Ordering) -> isize { + failure: Ordering) -> Result { unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } @@ -691,8 +699,8 @@ impl AtomicIsize { /// /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the /// comparison succeeds, which can result in more efficient code on some platforms. The - /// returned value is a tuple of the existing value and a flag indicating whether the - /// new value was written. + /// return value is a result indicating whether the new value was written and containing the + /// previous value. /// /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory /// ordering of this operation. The first describes the required ordering if the operation @@ -711,13 +719,9 @@ impl AtomicIsize { /// let mut old = val.load(Ordering::Relaxed); /// loop { /// let new = old * 2; - /// let result = val.compare_exchange_weak(old, new, - /// Ordering::SeqCst, - /// Ordering::Relaxed); - /// if result.1 { - /// break; - /// } else { - /// old = result.0; + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, /// } /// } /// ``` @@ -727,7 +731,7 @@ impl AtomicIsize { current: isize, new: isize, success: Ordering, - failure: Ordering) -> (isize, bool) { + failure: Ordering) -> Result { unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } } @@ -921,13 +925,16 @@ impl AtomicUsize { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn compare_and_swap(&self, current: usize, new: usize, order: Ordering) -> usize { - self.compare_exchange(current, new, order, strongest_failure_ordering(order)) + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } } /// Stores a value into the `usize` if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `current`, then the value - /// was updated. + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. /// /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this /// operation. The first describes the required ordering if the operation succeeds while the @@ -945,13 +952,13 @@ impl AtomicUsize { /// assert_eq!(some_isize.compare_exchange(5, 10, /// Ordering::Acquire, /// Ordering::Relaxed), - /// 5); + /// Ok(5)); /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); /// /// assert_eq!(some_isize.compare_exchange(6, 12, /// Ordering::SeqCst, /// Ordering::Acquire), - /// 10); + /// Err(10)); /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); /// ``` #[inline] @@ -960,7 +967,7 @@ impl AtomicUsize { current: usize, new: usize, success: Ordering, - failure: Ordering) -> usize { + failure: Ordering) -> Result { unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } @@ -968,8 +975,8 @@ impl AtomicUsize { /// /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the /// comparison succeeds, which can result in more efficient code on some platforms. The - /// returned value is a tuple of the existing value and a flag indicating whether the - /// new value was written. + /// return value is a result indicating whether the new value was written and containing the + /// previous value. /// /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory /// ordering of this operation. The first describes the required ordering if the operation @@ -988,13 +995,9 @@ impl AtomicUsize { /// let mut old = val.load(Ordering::Relaxed); /// loop { /// let new = old * 2; - /// let result = val.compare_exchange_weak(old, new, - /// Ordering::SeqCst, - /// Ordering::Relaxed); - /// if result.1 { - /// break; - /// } else { - /// old = result.0; + /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, /// } /// } /// ``` @@ -1004,7 +1007,7 @@ impl AtomicUsize { current: usize, new: usize, success: Ordering, - failure: Ordering) -> (usize, bool) { + failure: Ordering) -> Result { unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } } @@ -1206,13 +1209,16 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { - self.compare_exchange(current, new, order, strongest_failure_ordering(order)) + match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } } /// Stores a value into the pointer if the current value is the same as the `current` value. /// - /// The return value is always the previous value. If it is equal to `current`, then the value - /// was updated. + /// The return value is a result indicating whether the new value was written and containing + /// the previous value. On success this value is guaranteed to be equal to `new`. /// /// `compare_exchange` takes two `Ordering` arguments to describe the memory ordering of this /// operation. The first describes the required ordering if the operation succeeds while the @@ -1240,10 +1246,17 @@ impl AtomicPtr { current: *mut T, new: *mut T, success: Ordering, - failure: Ordering) -> *mut T { + failure: Ordering) -> Result<*mut T, *mut T> { unsafe { - atomic_compare_exchange(self.p.get() as *mut usize, current as usize, - new as usize, success, failure) as *mut T + let res = atomic_compare_exchange(self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure); + match res { + Ok(x) => Ok(x as *mut T), + Err(x) => Err(x as *mut T), + } } } @@ -1251,8 +1264,8 @@ impl AtomicPtr { /// /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the /// comparison succeeds, which can result in more efficient code on some platforms. The - /// returned value is a tuple of the existing value and a flag indicating whether the - /// new value was written. + /// return value is a result indicating whether the new value was written and containing the + /// previous value. /// /// `compare_exchange_weak` takes two `Ordering` arguments to describe the memory /// ordering of this operation. The first describes the required ordering if the operation @@ -1271,13 +1284,9 @@ impl AtomicPtr { /// let new = &mut 10; /// let mut old = some_ptr.load(Ordering::Relaxed); /// loop { - /// let result = some_ptr.compare_exchange_weak(old, new, - /// Ordering::SeqCst, - /// Ordering::Relaxed); - /// if result.1 { - /// break; - /// } else { - /// old = result.0; + /// match some_ptr.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + /// Ok(_) => break, + /// Err(x) => old = x, /// } /// } /// ``` @@ -1287,12 +1296,18 @@ impl AtomicPtr { current: *mut T, new: *mut T, success: Ordering, - failure: Ordering) -> (*mut T, bool) { - let result = unsafe { - atomic_compare_exchange_weak(self.p.get() as *mut usize, current as usize, - new as usize, success, failure) - }; - (result.0 as *mut T, result.1) + failure: Ordering) -> Result<*mut T, *mut T> { + unsafe { + let res = atomic_compare_exchange_weak(self.p.get() as *mut usize, + current as usize, + new as usize, + success, + failure); + match res { + Ok(x) => Ok(x as *mut T), + Err(x) => Err(x as *mut T), + } + } } } @@ -1370,8 +1385,8 @@ unsafe fn atomic_compare_exchange(dst: *mut T, old: T, new: T, success: Ordering, - failure: Ordering) -> T { - match (success, failure) { + failure: Ordering) -> Result { + let (val, ok) = match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new), @@ -1384,6 +1399,11 @@ unsafe fn atomic_compare_exchange(dst: *mut T, (_, Release) => panic!("there is no such thing as an acquire/release failure ordering"), (_, AcqRel) => panic!("there is no such thing as a release failure ordering"), _ => panic!("a failure ordering can't be stronger than a success ordering"), + }; + if ok { + Ok(val) + } else { + Err(val) } } @@ -1393,13 +1413,20 @@ unsafe fn atomic_compare_exchange(dst: *mut T, old: T, new: T, success: Ordering, - _: Ordering) -> T { - match success { + _: Ordering) -> Result + where T: ::cmp::Eq + ::marker::Copy +{ + let val = match success { Acquire => intrinsics::atomic_cxchg_acq(dst, old, new), Release => intrinsics::atomic_cxchg_rel(dst, old, new), AcqRel => intrinsics::atomic_cxchg_acqrel(dst, old, new), Relaxed => intrinsics::atomic_cxchg_relaxed(dst, old, new), SeqCst => intrinsics::atomic_cxchg(dst, old, new), + }; + if val == old { + Ok(val) + } else { + Err(val) } } @@ -1409,8 +1436,8 @@ unsafe fn atomic_compare_exchange_weak(dst: *mut T, old: T, new: T, success: Ordering, - failure: Ordering) -> (T, bool) { - match (success, failure) { + failure: Ordering) -> Result { + let (val, ok) = match (success, failure) { (Acquire, Acquire) => intrinsics::atomic_cxchgweak_acq(dst, old, new), (Release, Relaxed) => intrinsics::atomic_cxchgweak_rel(dst, old, new), (AcqRel, Acquire) => intrinsics::atomic_cxchgweak_acqrel(dst, old, new), @@ -1423,6 +1450,11 @@ unsafe fn atomic_compare_exchange_weak(dst: *mut T, (_, Release) => panic!("there is no such thing as an acquire/release failure ordering"), (_, AcqRel) => panic!("there is no such thing as a release failure ordering"), _ => panic!("a failure ordering can't be stronger than a success ordering"), + }; + if ok { + Ok(val) + } else { + Err(val) } } @@ -1432,11 +1464,10 @@ unsafe fn atomic_compare_exchange_weak(dst: *mut T, old: T, new: T, success: Ordering, - failure: Ordering) -> (T, bool) + failure: Ordering) -> Result where T: ::cmp::Eq + ::marker::Copy { - let result = atomic_compare_exchange(dst, old, new, success, failure); - (result, result == old) + atomic_compare_exchange(dst, old, new, success, failure) } #[inline] diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 49cacaac76627..05b8086de1314 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -725,6 +725,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, (_, name) if name.starts_with("atomic_") => { let split: Vec<&str> = name.split('_').collect(); + let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak"; let (order, failorder) = match split.len() { 2 => (llvm::SequentiallyConsistent, llvm::SequentiallyConsistent), 3 => match split[2] { @@ -733,16 +734,16 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, "acq" => (llvm::Acquire, llvm::Acquire), "rel" => (llvm::Release, llvm::Monotonic), "acqrel" => (llvm::AcquireRelease, llvm::Acquire), - "failrelaxed" if split[1] == "cxchg" || split[1] == "cxchgweak" => + "failrelaxed" if is_cxchg => (llvm::SequentiallyConsistent, llvm::Monotonic), - "failacq" if split[1] == "cxchg" || split[1] == "cxchgweak" => + "failacq" if is_cxchg => (llvm::SequentiallyConsistent, llvm::Acquire), _ => ccx.sess().fatal("unknown ordering in atomic intrinsic") }, 4 => match (split[2], split[3]) { - ("acq", "failrelaxed") if split[1] == "cxchg" || split[1] == "cxchgweak" => + ("acq", "failrelaxed") if is_cxchg => (llvm::Acquire, llvm::Monotonic), - ("acqrel", "failrelaxed") if split[1] == "cxchg" || split[1] == "cxchgweak" => + ("acqrel", "failrelaxed") if is_cxchg => (llvm::AcquireRelease, llvm::Monotonic), _ => ccx.sess().fatal("unknown ordering in atomic intrinsic") }, @@ -750,22 +751,17 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, }; match split[1] { - "cxchg" => { + "cxchg" | "cxchgweak" => { let cmp = from_immediate(bcx, llargs[1]); let src = from_immediate(bcx, llargs[2]); let ptr = PointerCast(bcx, llargs[0], val_ty(src).ptr_to()); - let res = AtomicCmpXchg(bcx, ptr, cmp, src, order, failorder, llvm::False); - ExtractValue(bcx, res, 0) - } - - "cxchgweak" => { - let cmp = from_immediate(bcx, llargs[1]); - let src = from_immediate(bcx, llargs[2]); - let ptr = PointerCast(bcx, llargs[0], val_ty(src).ptr_to()); - let val = AtomicCmpXchg(bcx, ptr, cmp, src, order, failorder, llvm::True); + let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False }; + let val = AtomicCmpXchg(bcx, ptr, cmp, src, order, failorder, weak); let result = ExtractValue(bcx, val, 0); let success = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx())); - Store(bcx, result, StructGEP(bcx, llresult, 0)); + Store(bcx, + result, + PointerCast(bcx, StructGEP(bcx, llresult, 0), val_ty(src).ptr_to())); Store(bcx, success, StructGEP(bcx, llresult, 1)); C_nil(ccx) } @@ -778,6 +774,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } to_immediate(bcx, AtomicLoad(bcx, ptr, order), tp_ty) } + "store" => { let val = from_immediate(bcx, llargs[1]); let ptr = PointerCast(bcx, llargs[0], val_ty(val).ptr_to()); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 3282d17d3a0c2..2cd166ebe7ebe 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -84,14 +84,10 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { //We only care about the operation here let (n_tps, inputs, output) = match split[1] { - "cxchg" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), - param(ccx, 0), - param(ccx, 0)), - param(ccx, 0)), - "cxchgweak" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), - param(ccx, 0), - param(ccx, 0)), - tcx.mk_tup(vec!(param(ccx, 0), tcx.types.bool))), + "cxchg" | "cxchgweak" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), + param(ccx, 0), + param(ccx, 0)), + tcx.mk_tup(vec!(param(ccx, 0), tcx.types.bool))), "load" => (1, vec!(tcx.mk_imm_ptr(param(ccx, 0))), param(ccx, 0)), "store" => (1, vec!(tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)), diff --git a/src/test/run-pass/atomic-compare_exchange.rs b/src/test/run-pass/atomic-compare_exchange.rs index 7946704709ce4..1d9fa248e3d93 100644 --- a/src/test/run-pass/atomic-compare_exchange.rs +++ b/src/test/run-pass/atomic-compare_exchange.rs @@ -16,22 +16,22 @@ static ATOMIC: AtomicIsize = ATOMIC_ISIZE_INIT; fn main() { // Make sure trans can emit all the intrinsics correctly - ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed); - ATOMIC.compare_exchange(0, 1, Acquire, Relaxed); - ATOMIC.compare_exchange(0, 1, Release, Relaxed); - ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed); - ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed); - ATOMIC.compare_exchange(0, 1, Acquire, Acquire); - ATOMIC.compare_exchange(0, 1, AcqRel, Acquire); - ATOMIC.compare_exchange(0, 1, SeqCst, Acquire); - ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst); - ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed); - ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed); - ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed); - ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed); - ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire); - ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire); - ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst); + ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Acquire, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Release, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok(); + ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); } diff --git a/src/test/run-pass/intrinsic-atomics.rs b/src/test/run-pass/intrinsic-atomics.rs index 3cc125e951334..a675528424ed2 100644 --- a/src/test/run-pass/intrinsic-atomics.rs +++ b/src/test/run-pass/intrinsic-atomics.rs @@ -15,9 +15,9 @@ mod rusti { extern "rust-intrinsic" { - pub fn atomic_cxchg(dst: *mut T, old: T, src: T) -> T; - pub fn atomic_cxchg_acq(dst: *mut T, old: T, src: T) -> T; - pub fn atomic_cxchg_rel(dst: *mut T, old: T, src: T) -> T; + pub fn atomic_cxchg(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_acq(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_rel(dst: *mut T, old: T, src: T) -> (T, bool); pub fn atomic_cxchgweak(dst: *mut T, old: T, src: T) -> (T, bool); pub fn atomic_cxchgweak_acq(dst: *mut T, old: T, src: T) -> (T, bool); @@ -56,13 +56,13 @@ pub fn main() { rusti::atomic_store_rel(&mut *x,1); assert_eq!(*x, 1); - assert_eq!(rusti::atomic_cxchg(&mut *x, 1, 2), 1); + assert_eq!(rusti::atomic_cxchg(&mut *x, 1, 2), (1, true)); assert_eq!(*x, 2); - assert_eq!(rusti::atomic_cxchg_acq(&mut *x, 1, 3), 2); + assert_eq!(rusti::atomic_cxchg_acq(&mut *x, 1, 3), (2, false)); assert_eq!(*x, 2); - assert_eq!(rusti::atomic_cxchg_rel(&mut *x, 2, 1), 2); + assert_eq!(rusti::atomic_cxchg_rel(&mut *x, 2, 1), (2, true)); assert_eq!(*x, 1); assert_eq!(rusti::atomic_xchg(&mut *x, 0), 1);