A release operation makes earlier work available to another thread when an acquire operation on the same atomic location synchronizes with it. The earlier work can include writes to non-atomic data: those writes are sequenced before the release and, through the release/acquire pair, happen before the acquiring thread’s later accesses. Release ordering alone does not establish that relationship; the corresponding acquire matters. section 5.3.7
Unlocking a spinlock
A spinlock’s lock() repeatedly calls flag.test_and_set(std::memory_order_acquire). Its unlock() calls flag.clear(std::memory_order_release). After one thread changes protected data and clears the flag, another thread’s successful acquisition synchronizes with that release. The protected changes therefore happen before the second thread accesses the data. section 5.3.7
void push(T const& data)
{
counted_node_ptr new_node;
new_node.ptr=new node(data);
new_node.external_count=1;
new_node.ptr->next=head.load(std::memory_order_relaxed)
while(!head.compare_exchange_weak(new_node.ptr->next,new_node,
std::memory_order_release,std::memory_order_relaxed));
}
In the stack’s push(), node construction and the write to next precede the successful compare_exchange_weak that publishes the node through head. That success needs release ordering so a later acquiring pop() can safely read next. A failed exchange publishes nothing, so its failure ordering is relaxed. section 7.2.5
void increase_head_count(counted_node_ptr& old_counter)
{
counted_node_ptr new_counter;
do
{
new_counter=old_counter;
++new_counter.external_count;
}
while(!head.compare_exchange_strong(old_counter,new_counter,
std::memory_order_acquire,std::memory_order_relaxed));
old_counter.external_count=new_counter.external_count;
}
The pop-side compare_exchange_strong uses acquire ordering on success. When it reads the head value published by push(), the release and acquire establish the happens-before relationship needed before accessing the node’s non-atomic next field. Failure can use relaxed ordering because the loop retries. section 7.2.5

