Reputation: 8270
C++ supported atomic thread fences, that is fences guaranteeing properties for thread that use std::atomic<>
operations, with the function atomic_thread_fence
. It takes a memory order parameter to adjust the "strength" of the fence.
I understand that fences are useful when not all atomic operations are done with a "strong" order:
(1) that includes RMW operations
So the usefulness of all these (acquire, release and acq_rel fences) is obvious: they allow threads that use atomic operations weaker than acq/rel (respectively) to synchronize properly.
But I don't understand where memory_order_seq_cst
could be specifically needed as a fence:
What's the implication of using weaker than memory_order_seq_cst
atomic operations and a memory_order_seq_cst
fence?
What would specifically be guaranteed (in term of possible ordering of atomic operations) by a memory_order_seq_cst
fence that wouldn't be guaranteed by memory_order_acq_rel
?
Upvotes: 6
Views: 1260
Reputation: 2949
No, a seq-cst-fence is not only both a release and an acquire-fence, but also provides some additional properties (see Working Draft, Standard for Programming Language C++, 32.4.4-32.4.8). A seq-cst fence is also part of the single total order of all sequentially consistent operations, enforcing the following observations:
memory_order_seq_cst
fence X sequenced before B, then B observes either the last memory_order_seq_cst
modification of M preceding X in the total order S or a later modification of M in its modification order.memory_order_seq_cst
fence X such that A is sequenced before X and B follows X in S, then B observes either the effects of A or a later modification of M in its modification order.memory_order_seq_cst
fences X and Y such that A is sequenced before X, Y is sequenced before B, and X precedes Y in S, then B observes either the effects of A or a later modification of M in its modification order.For example, I am using seq-cst fences in my hazard pointer implementation: https://github.com/mpoeter/xenium/blob/master/xenium/reclamation/impl/hazard_pointer.hpp
The thread acquiring a safe reference to some object uses seq-cst fence after storing the hazard pointer, but before re-reading the pointer to the object. The thread trying to reclaim some objects uses a seq-cst fence before gathering the active hazard pointers from all threads. Based on the rules above this ensures that either the thread trying to reclaim the object sees that some other thread has a HP for this object (i.e., the object is used), or the reload of thread trying to acquire the safe reference to the object returns a different pointer, indicating to that thread that the object has been removed and it has to perform a retry.
Upvotes: 3