Date: Thu, 11 Jun 2026 12:47:00 -0700
On Thursday, 11 June 2026 10:52:33 Pacific Daylight Time Jennifier Burnett
wrote:
> 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.
There would be one thread doing a store-release in the background, which these
two threads would synchronise with.
> ```
>
> T1:
> temp = TIME()
> <load-store barrier>
> y.store(1, relaxed)
> x.store(temp, relaxed)
>
> T2:
> w = x.load(relaxed)
> z = y.load(relaxed)
> <load-load barrier>
> temp = TIME()
> if (z) assert(w <= temp)
>
> ```
>
> Which allows reading z == 1, w == INT64_MAX.
I agree. I wasn't precise in my wording.
I meant that if you can tell that x was stored to, then it must have been
stored a value lesser than or equal to TIME(). That's the other assertion I
said:
assert(w == INT64_MAX || w <= TIME());
Specifically, we should be seeing:
x = INT64_MAX
y = 0
now = arbitrary value away from INT64_MAX
T1:
temp = TIME() // a.k.a. now.load(acquire)
x.store(temp, relaxed)
y.store(1, relaxed)
T2:
temp1 = x.load(relaxed)
temp2 = y.load(relaxed)
temp3 = TIME() // a.k.a. now.load(acquire)
assert(temp1 == INT64_MAX || temp1 <= temp3)
if (temp2)
assert(temp1 <= temp3)
Timing thread:
while (1) {
nanosleep(1);
now.fetch_add(1, release)
}
In this scenario, I think we can be certain the first assertion is always true.
The now.load() in T1 happens-before the store to x in that thread (a younger
load or store cannot bypass a the barrier) and the x.load() in T2 happens-
before the now.load() (an older load cannot bypass the barrier). Therefore, if
temp1 != INT64_MAX, then temp3 cannot be a value less than temp1.
The second assertion is not necessary, as you said. But this is now entirely
inside of the control of the programmer and should simply be developed to use
proper lock-free atomic semantics.
wrote:
> 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.
There would be one thread doing a store-release in the background, which these
two threads would synchronise with.
> ```
>
> T1:
> temp = TIME()
> <load-store barrier>
> y.store(1, relaxed)
> x.store(temp, relaxed)
>
> T2:
> w = x.load(relaxed)
> z = y.load(relaxed)
> <load-load barrier>
> temp = TIME()
> if (z) assert(w <= temp)
>
> ```
>
> Which allows reading z == 1, w == INT64_MAX.
I agree. I wasn't precise in my wording.
I meant that if you can tell that x was stored to, then it must have been
stored a value lesser than or equal to TIME(). That's the other assertion I
said:
assert(w == INT64_MAX || w <= TIME());
Specifically, we should be seeing:
x = INT64_MAX
y = 0
now = arbitrary value away from INT64_MAX
T1:
temp = TIME() // a.k.a. now.load(acquire)
x.store(temp, relaxed)
y.store(1, relaxed)
T2:
temp1 = x.load(relaxed)
temp2 = y.load(relaxed)
temp3 = TIME() // a.k.a. now.load(acquire)
assert(temp1 == INT64_MAX || temp1 <= temp3)
if (temp2)
assert(temp1 <= temp3)
Timing thread:
while (1) {
nanosleep(1);
now.fetch_add(1, release)
}
In this scenario, I think we can be certain the first assertion is always true.
The now.load() in T1 happens-before the store to x in that thread (a younger
load or store cannot bypass a the barrier) and the x.load() in T2 happens-
before the now.load() (an older load cannot bypass the barrier). Therefore, if
temp1 != INT64_MAX, then temp3 cannot be a value less than temp1.
The second assertion is not necessary, as you said. But this is now entirely
inside of the control of the programmer and should simply be developed to use
proper lock-free atomic semantics.
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-06-11 19:47:09
