Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The memory order Acquire in self.state.swap(WAITING, AcqRel); is not necessary #19

Open
xmh0511 opened this issue Oct 17, 2024 · 1 comment

Comments

@xmh0511
Copy link

xmh0511 commented Oct 17, 2024

let res = self
    .state
    .compare_exchange(REGISTERING, WAITING, AcqRel, Acquire);  // #1
match res {
   Ok(_) => {}
   Err(actual) => {
    // This branch can only be reached if at least one
    // concurrent thread called `wake`. In this
    // case, `actual` **must** be `REGISTERING |
    // `WAKING`.
     debug_assert_eq!(actual, REGISTERING | WAKING);
     let waker = (*self.waker.get()).take().unwrap();
    // We need to return to WAITING state (clear our lock and
    // concurrent WAKING flag). This needs to acquire all
    // WAKING fetch_or releases and it needs to release our
    // update to self.waker, so we need a `swap` operation.
     self.state.swap(WAITING, AcqRel);  // #2
    // ...
  }
}

As shown in the comment, the Err(actual) branch can only be reached if there is a concurrent wake invoked during the REGISTERING, since the load part of compare_exchange is Acquire, and the writing part of self.state.fetch_or(WAKING, AcqRel) is Release, that is, #1 has synchronized with self.state.fetch_or, the reading part of #2 is unnecessary to be Acquire.

IIUC, self.state.swap(WAITING, AcqRel); can be changed to self.state.swap(WAITING, Release);

@xmh0511
Copy link
Author

xmh0511 commented Oct 17, 2024

Or, the purpose is to ensure #2 synchronizes with another intervening wake that occurred during the branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant