Fix atomicity of Edge accesses
Currently mmtk_ghc::edges::Edge::{load,store}
use non-atomic accesses which is problematic in the presence of parallelism. In principle addressing this should be a matter of:
diff --git a/rts/mmtk/mmtk/src/edges.rs b/rts/mmtk/mmtk/src/edges.rs
index e68b1fc1066..f9d24c388b6 100644
--- a/rts/mmtk/mmtk/src/edges.rs
+++ b/rts/mmtk/mmtk/src/edges.rs
@@ -86,8 +86,8 @@ impl Edge for GHCEdge {
fn load(&self) -> ObjectReference {
match self {
GHCEdge::ClosureRef(c) => unsafe {
- let cref: *mut TaggedClosureRef = c.0;
- let closure_ref: TaggedClosureRef = *cref; // loads the pointer from the reference field
+ let ptr = unsafe { std::sync::atomic::AtomicPtr::from_ptr(c.0) };
+ let closure_ref: TaggedClosureRef = ptr.load(std::sync::atomic::Ordering::Acquire); // loads the pointer from the reference field
let addr: Address = closure_ref.to_address(); // untags the pointer
ObjectReference::from_raw_address(addr) // converts it to an mmtk ObjectReference
},
@@ -132,8 +132,9 @@ impl Edge for GHCEdge {
GHCEdge::ClosureRef(c) => unsafe {
// get the tag from old address and apply to the new value
let tag: usize = (*(c.0)).get_tag();
- let cref = TaggedClosureRef::from_address(object.to_raw_address());
- *(c.0) = cref.set_tag(tag);
+ let cref = TaggedClosureRef::from_address(object.to_raw_address()).set_tag(tag);
+ let ptr = unsafe { std::sync::atomic::AtomicPtr::from_ptr(c.0) };
+ ptr.store(cref, std::sync::atomic::Ordering::Release);
},
GHCEdge::FunSrtRef(_) | GHCEdge::ThunkSrtRef(_) | GHCEdge::RetSrtRef(_) => {
debug_assert_eq!(self.load(), object, "Attempted to store a different value into an SrtRef")
However, it appears that AtomicPtr::from_ptr
isn't currently stable: https://github.com/rust-lang/rust/issues/108652.