Search code examples
multithreadingrustconcurrency

Rust: Memory ordering, fence(Release) and fence(Acquire)


In the book: Rust Atomics and Locks, on the part on fence (std::sync::atomic::fence) (Chapter 3, page 68), the author gave the example below and made the following claim.

Thread 1:                 Thread 2: 
fence(Release);           A.load(Relaxed); 
A.store(1, Relaxed);      B.load(Relaxed); 
B.store(2, Relaxed);      C.load(Relaxed); 
C.store(3, Relaxed);      fence(Acquire); 

The claim:

In this situation, if any of the load operations on thread 2 loads the value from 
the corresponding store operation of thread 1, the acquire fence on thread 2 happens- 
before the release fence on thread 1.

However, what I don't understand is this: how can 'the acquire fence on thread 2 happens-before the release fence on thread 1'? On the same page as the claim, the author says, "it means that a happens-before relationship is created between a release fence and an acquire fence if any store after the release fence is observed by any load before the acquire fence". She did not clarify which is the former and which is the latter.

The total modification order ('all modifications of the same atomic variable happen in an order that is the same from the perspective of every single thread', as defined on page 54, Chapter 3) of say atomic variable A should be 1 if A.load(Relaxed) reads 1 on Thread 2 and that should mean the release fence on thread 1 happens-before the acquire fence on thread 2.

Why did the author claim otherwise?


Solution

  • This is a mistake in the book, and it's listed in the errata. (Always good to search for when you're confused about something in a book!)

    It should be the other way around: the release fence happens before the acquire fence.