I was looking for something that would compile to the magical cmpxchg
instruction. After digging into the documentation, I couldn't find anything that would accomplish this for Cell
.
Maybe this is an antipattern?
After digging into the code I added the following to Cell
's implementation to see if it would work.
pub fn cmp_and_set(&self, old: T, new: T) -> T {
unsafe {
::intrinsics::atomic_cxchg(self.value.get(), old, new)
}
}
// ^ there are many many reasons why this is not so great
// this is just an example of what I'm looking for
simple usage
fn main() {
let c0 = Cell::new(10);
let val0 = c0.cmp_and_set(11, 5);
assert_eq!(c0.get(), 5);
let val1 = c0.cmp_and_set(10, 42);
assert_eq!(c0.get(), 42);
}
As far as I can tell, for very basic cases it works, but again there are many many reasons why the particular implementation is less than stellar. The fact that I edited the standard library to get what I was looking for means I'm certainly attempting to implement some sort of antipattern.
This was prompted from re-reading the following from The Rust Programming Language
It is still possible to violate your own invariants using this wrapper, so be careful when using it. If a field is wrapped in
Cell
, it's a nice indicator that the chunk of data is mutable and may not stay the same between the time you first read it and when you intend to use it.
TL;DR: No, there's not, because it's unnecessary.
Compare and Set is only valuable in two actors (or more) are modifying the object in parallel.
While Cell
allows internal mutability, it is not thread-safe, so you will never be in a situation where two actors will be attempting to modify it in parallel.
Therefore, you can just use get()
, compare, and set()
if it suits you. And nobody will change the value between your get()
and set()
, providing you do not call other code yourself.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments