Consider the following code:
struct payload
{
std::atomic< int > value;
};
std::atomic< payload* > pointer( nullptr );
void thread_a()
{
payload* p = new payload();
p->value.store( 10, std::memory_order_relaxed );
std::atomic_thread_fence( std::memory_order_release );
pointer.store( p, std::memory_order_relaxed );
}
void thread_b()
{
payload* p = pointer.load( std::memory_order_consume );
if ( p )
{
printf( "%d\n", p->value.load( std::memory_order_relaxed ) );
}
}
Does C++ make any guarantees about the interaction of the fence in thread a with the consume operation in thread b?
I know that in this example case I can replace the fence + atomic store with a store-release and have it work. But my question is about this particular case using the fence.
Reading the standard text I can find clauses about the interaction of a release fence with an acquire fence, and of a release fence with an acquire operation, but nothing about the interaction of a release fence and a consume operation.
Replacing the consume with an acquire would make the code standards-compliant, I think. But as far as I understand the memory ordering constraints implemented by processors, I should only really require the weaker 'consume' ordering in thread b, as the memory barrier forces all stores in thread a to be visible before the store to the pointer, and reading the payload is dependent on the read from the pointer.
Does the standard agree?
std::memory_order_consume
only gave you appropriate consume semantics if the corresponding store is tagged with eitherrelease
,acq_rel
, orseq_cst
. So theconsume
load might have the same guarantees if it were instead tagged withrelaxed
, since the store topointer
is alsorelaxed
. – Alejandrostd::atomic_thread_fence( std::memory_order_release )
is to generate a delayed "tag" for the previous last relaxed stores; IOW you can say that a release store is an immediate named store barrier, unlike the anonymous delayed barrier by a fence (a named barrier works on only that object, an anonymous applies to each one). – curiousguy