C++ Logo

std-discussion

Advanced search

Re: Does the C++ abstract machine recognize a temporal order of execution?

From: Jennifier Burnett <jenni_at_[hidden]>
Date: Thu, 11 Jun 2026 18:52:33 +0100
Do just want to point out that the proposed barrier isn't a standard c++ acquire barrier but a new magic barrier that would need new semantics, c++ acquires are meaningless without a corresponding release (since it only establishes a happens-before between things after the acquire and things before the release) and so would do nothing, or could only synchronise with the incrementing thread as you said before.

In my example I was treating x, z, and w as regular local variables, with the idea that w >= x would be checked after both threads of execution are complete.

On 11 June 2026 18:01:40 BST, Thiago Macieira via Std-Discussion <std-discussion_at_[hidden]> wrote:
>On Thursday, 11 June 2026 00:44:31 Pacific Daylight Time Jennifier Burnett via
>Std-Discussion wrote:
>> ```
>> T1:
>> x = TIME()
>> y.store(x, relaxed)
>>
>> T2:
>> z = y.load(relaxed)
>> w = TIME()
>> ```
>> To my understanding the question as you understand it is whether when z ==
>> x, w must >= x, correct?
>
>Thank you for making this a more concrete example, but I don't think it went
>far enough: you didn't model x as an atomic, so it's hard to say how one can
>perform the w >= x check in the first place.
>
>Let's say though:
>x = INT64_MAX
>y = 0
>T1:
> x.store(TIME(), relaxed)
> y.store(1, relaxed)
>
>T2:
> z = y.load(relaxed)
> w = x.load(relaxed)
> if (z) assert(w <= TIME())
>
>If we didn't know what TIME() was (let's say it was a constant), this is the
>prototypical example of how loads and stores can bypass each other: it's
>entirely possible for y.store() to have become visible, but not x.store(),
>resulting in T2 seeing x's old value of INT64_MAX and failing the assertion.
>
>Nothing changes even if we model TIME() as a load(relaxed) of a global that
>monotonically increases at a frequency of 1 GHz. There would be no happens-
>before between the two pairs of variables, so in T1 it would be entirely
>allowable for the y.store(1) to finish and becoming readable before obtaining
>the time in the first place. Likewise in T2, the x.load() could happen earlier
>than the y.load(), so it might see the old value of x (INT64_MAX) even if y
>was seen as 1.
>
>What if TIME() has an acquire fence? In this case, the machine cannot reorder
>a younger store ahead of it. This ensures that neither store in T1 can become
>observable before the TIME() read. Likewise, it does prevent the reordering if
>the loads in T2 against the TIME() load, so if x *was* updated, then the
>assertion holds.
>
>But it doesn't help with the relative ordering of x and y between themselves.
>So this works:
> assert(w == INT64_MAX || w <= TIME());
>
>but not as written above, because nothing prevents observing y.load() from
>observing 1 while x.load() still observes the old value.
>

Received on 2026-06-11 17:52:41