Skip to content

Aliasing-motivated concurrency optimizations #572

Open
@gonzalobg

Description

@gonzalobg

The following tests capture some of the interactions between aliasing and concurrency.
While the optimizations below may introduce a data-race, any such execution is undefined due to aliasing violations: they'd need to access memory through a reference that's not derived from the &mut.
I don't see any immediate harm in these being allowed, but I found these being allowed by Rust and LLVM-IR interesting, to say the least.

The comments capture what I believe is the "status-quo", everyone should decide for themselves whether they think those executions should be allowed or forbidden:

pub fn test0(b: &mut u32){
  loop {
     let a = AtomicU32::from_mut(b);
     if a.load(Ordering::Relaxed) != 0 { // may be downgraded to non-atomic access
        break;
     }
  }
  *b = 42;
}

pub fn test1(b: &mut u32) -> u32 {
  let x = *b;
  fence(Ordering::Release); // may be re-ordered above load; analogous for store-release
  x
}

pub fn test2(b: &mut u32) {
  *b = 42;
  fence(Ordering::Release); // may be re-ordered above store; analogous for store-release
}

pub fn test3(b: &mut u32) {
  fence(Ordering::Acquire); // analogous for load-acquire
  *b = 42; // may be re-ordered above fence
}

pub fn test4(b: &mut u32) -> u32 {
  fence(Ordering::Acquire); // analogous for load-acquire
  *b // may be re-ordered above fence
}

The examples above are very simple and don't involve allocation APIs.
The following references include many other examples, some of which may be interesting to adapt to Rust.
Particularly interesting are those involving concurrency and "lifetime start"/"end" (memory being allocated/deallocated).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions