Reputation: 3822
Consider following example:
-Thread 1-
y.store (20, memory_order_relaxed);
x.store (10, memory_order_release);
-Thread 2-
if (x.load(memory_order_acquire) == 10) {
assert (y.load(memory_order_relaxed) == 20)
y.store (10, memory_order_release)
}
-Thread 3-
if (y.load(memory_order_acquire) == 10)
assert (x.load(memory_order_relaxed) == 10)
In this example second assert
will fire(am i correct?). is it because there is no store to x
in thread 2 before y.store (10, memory_order_release)
?
(in cppreference.com they say this sentence about release
: "A store operation with this memory order performs the release operation: prior writes to other memory locations become visible to the threads that do a consume or an acquire on the same location.")
Can i change the order of store to y
in thread2 from release
to sec/cst
to solve the problem?
Upvotes: 0
Views: 130
Reputation: 300
Your example isn't complete because you haven't specified initial values for x & y. But let's assume that the thread that starts all threads has initialized both to 0.
Then if thread 2 does a store to y, it must have read from thread 1's store to x and synchronized with it. If thread 3's load from y reads thread 2's store to y, it must synchronize also. Therefore, the store to x in thread 1 must happen before the load in thread 3 and it must happen after the initialization store to x. Thus thread 3's x.load must get the value of 10. Happens before in the absence of consume is transitive.
I suggest using CDSChecker on these examples to see what values are possible.
Upvotes: 2