[concurrency-interest] "Volatile-like" guarantees

Niko Matsakis niko at alum.mit.edu
Wed Feb 2 14:20:08 EST 2011


Hello everyone,

I have a question about the Java Memory Model.  I am trying to decide if 
it is possible to use a dummy volatile field, like the field v below, to 
get the same guarantees as an actual volatile field.  In other words, is 
the class Foo shown here equivalent to a class where the the field f is 
declared volatile:
>     class Foo {
>         private volatile int v;
>         private int f;
>
>         void setF(int x) {
>             v = 0;    // Wv
>             x = f;    // Wf
>         }
>
>         int getF() {
>             int x = f;     // Rf
>             int y = v;    // Rv
>             return x;
>         }
>     }
In particular, would code using the accessors shown above still be 
sequentially consistent, as it would be if "f" were volatile?

Clearly, the program is not data-race free as defined by the JMM, 
because the write Wf does not happen before Rf.  Nonetheless, I believe 
there is a guarantee very much like the one that volatile offers, which 
I will call "volatile-like":
> If Rf sees the value written by Wf, then no subsequent read will see a 
> write that was overwritten before the write Wv occurred.  More 
> formally, no read r that happens after Rv, which includes all reads in 
> the thread calling getF(), will see a write w that happens before Wv 
> where there exists another write w' such that w -> w' -> Wv.
An informal argument can be found below [1].  I believe that this 
"volatile-like" guarantee implies sequential consistency, in the same 
way that the volatile guarantee would (argument [2] below).  However, I 
ALSO believe that the JMM is fairly subtle, and I may well be missing 
something. :) Hence my e-mail to this list.

One particular concern I have is the possibility that a compiler might 
observe that all the writes to the volatile field "v" are of the same 
value, 0, and therefore eliminated the field.  (A similar example 
appears in the JMM paper I have been consulting).  I believe however 
that this ought to be illegal by the JMM, as "v" is volatile and 
therefore induces happens-before relations in addition to carrying a value.

I thank all of you in advance, both for taking the time to read this 
e-mail and for any insight you may provide.


regards,
Niko

-----

[1] The argument that Rf/Wf have a "volatile-like" relationship is as 
follows:

First, the only important cases are those where Rf sees the write Wf.  
This is because the "volatile-like" guarantees described above only 
concern what happens when Rf sees the write Wf.  As the volatile 
accesses Wv and Rv are both synchronization actions, one must happen 
before the other in any particular execution.  If Rv happens before Wv, 
then at the time when field f is read, Wf cannot be visible, because Rf 
-> Rv -> Wv -> Wf.  Therefore, Rf cannot see the write Wf, and this case 
is not important.

If Wv happens before Rv, then when Rf executes, it is possible that Wf 
has already been committed.  In that case, Rf may legally see the value 
written by Wf, as it would not violate happens-before consistency (Rf 
does not happen before Wf, nor is there a write w such that Wf -> w -> 
Rf).  However, those same happens-before consistency requirements, 
combined with the happens-before relation from Wv to Rv, guarantee that 
any reads that happen after Rv will not see overwritten writes that 
happen before Wv.

[2] A rather loose argument for sequential consistency is that if there 
were two instances of this class Foo f1 and f2, and thread T1 performed 
{ f1.setF(w1); f2.setF(w2); } where another thread T2 performed { int r2 
= f2.getF(); int r1 = f1.getF(); }, it should be impossible for T2 to 
observe w2 but not w1.  Why?  Because the write of w1 happens before the 
write of w2 (presumably overwriting the value written by some previous 
write w).  Therefore, by the "volatile-like" guarantee on f2.f, the 
subsequent read of f1.f cannot see the write w, as w -> write of w1 -> 
write of w2.  A better argument would probably construct a sequentially 
consistent equivalent to any schedule, but I haven't tried writing such 
a thing out yet.


More information about the Concurrency-interest mailing list