I've been reading about C++ memory models and think I have a grasp of the basic concepts of happens-before, synchronizes-with and inter-thread happens-before. However, applying them in some examples has been difficult. In particular I have been thinking about the following sequence of operations when they are repeated:
Thread 1
1. Atomic store of X in A (seq cst).
2. Write X to B.
3. Atomic store of X in C (seq cst).
Thread 2
4. Atomic load of C.
5. Read of B.
6. Atomic load of A.
Now I know that following 4 Thread 2 must see the write made by Thread 1 in 2, but what happens if Thread 1 is spinning and after 3 is setting A then B and then C to Y? I think Thread 2 can see C set to X and B to Y because Thread 1 can have set A and B to Y but not set C to Y yet. This much is clear, but if Thread 2 checks A and finds it is set to X, does that mean Thread 2 must also see B set to X? I've written some code to spin Thread 1 and Thread 2 and found that if Thread 2 sees the same value for A and C then B also has the same value. I know however this does not prove it, which is the reason for this question.
I think the key thing is whether the atomic store in 1 implies anything about the store in 2? If 2 had been done before 1 then it does but that's not the case here. If the result of 2 is seen by Thread 2 before it sees the results of 1 and 3 then Thread 2 would see A and C set to X but B set to Y. Is this possible? How would that be described given the concepts above. Finally, is some other factors coming into play that may mean the program I wrote does work (on x86)?