Reputation: 2968
So in rust, I am trying to see what result is given when a AtomicPtr.compare_exchange()
fails, where the expected value is not what is actually contained. I have the following code:
use std::sync::atomic::{AtomicPtr, Ordering};
pub fn foo() {
let ptr = &mut 5;
let ptr2 = &mut 6;
let atomic_ptr = AtomicPtr::new(ptr);
unsafe {
match atomic_ptr.compare_exchange(ptr, ptr2, Ordering::SeqCst, Ordering::SeqCst) {
Ok(got) => println!("Worked got {}", *got),
Err(nogot) => println!("Failed got {}", *nogot),
}
}
}
pub fn bar() {
let ptr = &mut 5;
let ptr2 = &mut 6;
let atomic_ptr = AtomicPtr::new(ptr);
unsafe {
match atomic_ptr.compare_exchange(ptr2, ptr2, Ordering::SeqCst, Ordering::SeqCst) {
Ok(got) => println!("Worked got {}", *got),
Err(nogot) => println!("Failed got {}", *nogot),
}
}
}
fn main() {
foo();
bar();
}
But this prints
Worked got 5
Failed got 5
It seems both success and fail for the compare exchange give the currently held pointer. Is this truly the case? Or am I missing something here? The docs don't document what the Result
gives on failure either https://doc.rust-lang.org/std/sync/atomic/struct.AtomicPtr.html#method.compare_exchange
Upvotes: 0
Views: 995
Reputation: 42492
It seems both success and fail for the compare exchange give the currently held pointer. Is this truly the case?
Yes.
The docs don't document what the Result gives on failure either
They do, though the wording obscures it:
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 current.
This is actually 3 completely separate clauses:
Ok
) -- implies that it's an Err
on failurecurrent
-- obviously on failure the current
you provided was wrong, so you get something else (the actual current value)Either opening a documentation issue or a documentation PR to clarify this would probably be welcome, though beware that this issue seems to be duplicated on all three implementations of compare_exchange
so you'll probably have to fix them all if you go the PR route: all integer types are implemented via a common macro but AtomicPtr
and AtomicBool
have their own copies of the entire interface.
Upvotes: 3