New memory ordering where added in JDK9, so I'm digging into Release/Acquire mode. It introduce causality constraint:
If access A precedes interthread Release mode (or stronger) write W in source program order, then A precedes W in local precedence order for thread T
If interthread Acquire mode (or stronger) read R precedes access A in source program order, then R precedes A in local precedence order for Thread T.
As far as I see, the best way to show distinguish between R/A and Volatile modes is IRIW:
int x = 0
int y = 0
|-----------|-----------|--------------|--------------|
| Thread 1 | Thread 2 | Thread 3 | Thread 4 |
|-----------|-----------|--------------|--------------|
| setM(x,1) | setM(y,1) | r1 = getM(x) | r3 = getM(y) |
| | | r2 = getM(y) | r4 = getM(x) |
|-----------|-----------|--------------|--------------|
If getM/setM
is getAcquire/setRelease
result (r1, r2, r3 ,r4) = (1, 0, 1, 0)
is allowed;
If getM/setM
is getVolatile/setVolatile
result (r1, r2, r3 ,r4) = (1, 0, 1, 0)
is forbidden;
My main target is to show that causality (from RA) != happens-before (in terms of JLS)
To show it I want to proof that for IRIW-volatile case result (1, 0, 1, 0)
is forbidden using only happens-before (without using sequential consistency):
volatile int x = 0;
volatile int y = 0;
|----------|----------|----------|----------|
| Thread 1 | Thread 2 | Thread 3 | Thread 4 |
|----------|----------|----------|----------|
|a: x = 1 |b: y = 1 |c: r1 = x |e: r3 = y |
| | |d: r2 = y |f: r4 = x |
|----------|----------|----------|----------|
Result of execution: (r1, r2, r3, r4)
= (1, 0, 1, 0)
Happens-before orderings:
T1.W(x,1) -hb→ T3.R(x):1 -hb→ T3.R(y):0
T2.W(y,1) -hb→ T4.R(y):1 -hb→ T4.R(x):0
T1.W(x,1) -not hb→ T4.R(x):0
T2.W(y,1) -not hb→ T3.R(y):0
Synchronization Order:
We don't know it yet now, it's just some permutation of tuple (a, b, c, d, e, f)
, let's imagine it as array of 6 elements (SO array
);
Synchronized-with is order defined for some SO
-subsequent actions), so:
if A -sw→ B then A appears before B in SO array
SO is consistent with Program Order, so:
if A -po→ B then A appears before B is SO array
Happens-before is transitive closure of SW and PO, so:
if A -hb→ B then A appears before B is SO array
Due to happens-before orderings №1, №2 we have:
a appears before c is SO array
c appears before d is SO array
b appears before e is SO array
e appears before f is SO array
This means that last element in SO-array is f
or d
If last element is f
than we have a appears before f
is SO, this means a -sw→ f
, this causes a -hb→ f
: inconsistency with happens-before ordering №3
(for case when last element is d
the reasoning is similar)
This means that result (1, 0, 1, 0)
is not possible here.
Is it proof correct?
Is it correct way to show that happens-before relation from JLS is not equivalent of causality RA constraint and you can't use term happens before
for RA chains?
Yes, your proof is correct (at least as I can see).
Yes, IRIW is clear and simple example that demostrates differences between Release/Acquire and Volatile modes.
You can also use this in your proof: volatile read
always returns the latest volatile write
to that variable in synchronization order.
Here is the quote from the JLS:
17.4.7. Well-Formed Executions
We only consider well-formed executions. An execution
E = < P, A, po, so, W, V, sw, hb >
is well formed if the following are true:...
The execution obeys synchronization-order consistency.
For all volatile reads
r
inA
, it is not the case that eitherso(r, W(r))
or that there exists a writew
inA
such thatw.v = r.v
andso(W(r), w)
andso(w, r)
.
The rest is similar to your proof:
so
is a total order consistent with po
=> either d
or f
must be the last action in so
volatile write
of 1 to the same variable before the volatile read
in so
=> the volatile read
must return 1Also it's important to mention that even though the article you quoted is written by the author of JDK 9 Memory Order Modes, it's not official documentation.
This means that at any moment the implementation of the Memory Order Modes might be changed from what's described in the article.
The the only real guarantees are given in the official documentation, and AFAIK today it is just this javadoc.