Reordering around SeqCst, and tokio watch

⚓ rust    📅 2025-05-20    👤 surdeus    👁️ 3      

surdeus

Warning

This post was published 41 days ago. The information described in this article may have changed.

I am a little confused about memory reordering when it comes to SeqCst. The documentation for Ordering at Ordering in std::sync::atomic - Rust says that SeqCst behaves like Acquire/Release/AcqRel, along with extra features.

This would lead me to think that the following is true. Suppose in one thread T we have a Relaxed store of 666 to an AtomicU64 A, followed by a SeqCst store of 777 to an AtomicU64 B.

Suppose in another thread U, we do a SeqCst load on B and get the same 777 value. We subsequently do a Relaxed load on A.

Are we guaranteed to see 666? If not, why?

ChatGPT suggests using a Release store on A in T, and an Acquire load on A in U. I am not convinced that this would make any difference.

If ChatGPT is correct, why would Acquire/Release prevent reordering after/before the SeqCst operations, and why would the Relaxed operations potentially be reordered?

If, as in the linked documentation, SeqCst works like Acquire/Release/AcqRel, then why would we need Release/Acquire on A instead of Relaxed?

The reason why I'm asking this is that I am storing (Relaxed) to an atomic before calling send on a tokio watch sender, and loading (Relaxed) from the same atomic after the changed method on the watch returns. I know that tokio watch uses SeqCst internally. Therefore I would hope that the Relaxed store to the atomic before calling send on the watch, would be visible to the Relaxed load called after "changed" has returned.

If what I am currently doing does not solve this, what is the best way to enforce memory ordering on atomics when using tokio watch?

6 posts - 3 participants

Read full topic

🏷️ rust_feed