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;
int dummynv;
/* Assume for this example that
the first write has already begun, with v=1, a=any, b=any */
...
a = 2;
b = 3;
v++;
... /* other operations between first and second write */
v++;
dummynv = dummyv; /* Read of dummy volatile */
a=5;
b=7;
v++;
Reader thread:
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 
interpretation?
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 
interpretation.
Sylvia.
-------------------------------
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