I've thought some more about this. The required happens-before edge can be
added by means of a write and read of a dummy volatile.
volatile v, dummyv;
/* Assume for this example that
the first write has already begun, with v=1, a=any, b=any */
a = 2;
b = 3;
... /* other operations between first and second write */
dummynv = dummyv; /* Read of dummy volatile */
t1 = v;
x = a;
y = b;
r = a*b;
dummyv = 0; /* Write of dummy volatile */
t2 = v;
if (t1 == t2 && t1%2 == 0) return(r);
else /* redo */
Now we have that dummyv = 0 is ordered before t2 = v in the synchronization
order, which has to correspond to program order. Similarly, dummynv =
dummyv is ordered after v++.
As I previously commented, t2 = v is ordered before the v++ that sets v to
3. This is because otherwise it would have to be ordered after it, and
there would be a happens-before edge that would prevent the read of v from
seeing the value 2.
So dummyv = 0 is ordered before dummynv = dummyv. This creates a
happens-before edge from dymmyv = 0 to dummynv = dummyv.
If there are multiple readers, this only works under the strong
interpretation. Is this, or something similar, what was being referred to
as being the previously described pattern that breaks under the weak
It seems a bit odd that an optimiser could remove these statements, leaving
only the happens-before relationships that they create.
The dummy volatile could be removed if the t2 = v were replaced by an
atomic compare and swap from JSR166. This would work under the weak
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:03 EDT