Search code examples
clanguage-lawyeratomicstdatomicsequence-points

Relationship between C11 atomics and sequence points


I basically have the following code snippet:

size_t counter = atomic_fetch_sub_explicit(&atomicCounter, 1, memory_order_release);
if (counter - 1 == 0
    && atomic_load_explicit(&anotherAtomicCounter, 1, memory_order_relaxed) == 0 {
      //Some code
}

For correctness, it is important that the atomic load of anotherAtomicCounter occurs after the fetch-and-sub (FAS) of atomicCounter. With the given memory orders, this would normally not be guaranteed and the load could happen before the FAS. However, I was wondering how sequence points have an affect on this particular code. The standard mentions that

If evaluation A is sequenced before evaluation B, then evaluation of A will be complete before evaluation of B begins.

Combined with rule number 2

There is a sequence point after evaluation of the first (left) operand and before evaluation of the second (right) operand of the following binary operators: && (logical AND), || (logical OR), and , (comma).

this means that the atomic load must happen after the comparison but the comparison can only be completed once the result of the FAS is known.

My question is whether these rules guarantee that the atomic load always happens after the FAS, even when using more relaxed memory orders?

Thanks in advance!


Solution

  • To answer the question in your title, there is no real relationship between atomics and sequence points.

    The code as written does guarantee that the compiler must execute the atomic_fetch_sub before the atomic_load. But these functions are (in C's memory model) simply requests to the platform to perform certain actions on certain pieces of memory. Their effects, when they become visible to who, are specified by the memory model, and the ordering parameters. Thus even in the case when you know request A comes before request B, that does not mean the effects of request A are resolved before request B, unless you explicitly specify it to be.