[concurrency-interest] Using a volatile variable as a "guard"

Boehm, Hans hans.boehm at hp.com
Mon Feb 7 14:50:47 EST 2011


I personally still think that by far the cleanest way to think about whether a variable should be volatile is to ask:

Does it participate in a data race?  Can one thread be reading or writing it while another thread is writing it?  To answer this question use a simple interleaved ("sequentially consistent") model in which nothing can be reordered.  In VolatileExample below (continuing to assume a single writer) x does not participate in a data race, since x is accessed by the reader only after it sees v true, and thus the writer must be done.  v can clearly participate in a data race, as can factory and isNuclearFactory in the original example.

This does assume that:

1) You apply this rule consistently.  If you don't declare v in the example below volatile, then the sequentially consistent reasoning I used to argue that x doesn't participate in a data race doesn't hold, since I no longer have a data-race-free program.

2) Library implementers do the same, or at least make sure that library APIs are defined such that clients can continue to use sequentially consistent reasoning.  Currently, I think that's a goal of nearly all standard library APIs, at least in all cases in which reasonable client code can tell.  I suspect there are remaining bugs in some of the details.  But none of these issues arise in these examples.

3) The program is otherwise correct under sequentially consistent reasoning.

Hans

> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu [mailto:concurrency-
> interest-bounces at cs.oswego.edu] On Behalf Of David Holmes
> Sent: Monday, February 07, 2011 2:12 AM
> To: Yan Cheng CHEOK; concurrency-interest at cs.oswego.edu;
> dholmes at ieee.org
> Subject: Re: [concurrency-interest] Using a volatile variable as a
> "guard"
> 
> Yan Cheng Cheok writes:
> > In that case, is it correct for me to make the following 2
> conclusion?
> >
> > Based on
> > http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#inco
> > rrectlySync,
> >
> > class VolatileExample {
> >   int x = 0;
> >   volatile boolean v = false;
> >   public void writer() {
> >     x = 42;
> >     v = true;
> >   }
> >
> >   public void reader() {
> >     if (v == true) {
> >       //uses x - guaranteed to see 42.
> >     }
> >   }
> > }
> >
> > Conclusion 1
> > ============
> > 1a) write to non-volatile variable x
> > 1b) write to volatile variable v
> > 1a can never moved pass 1b
> >
> > and based on the need of using volatile in NuclearFactory example.
> >
> > Conclusion 2
> > ============
> > 2a) write to volatile variable v
> > 2b) write to non-volatile variable x
> > 2b can moved before 2a
> 
> Correct on both counts. A read of a volatile has a acquire semantics; a
> write to a volatile has release semantics. Given:
> 
>   acquire();
>   ...
>   release();
> 
> we informally talk about  the "Roach Motel" rules - you can move in (to
> the
> ... region) but you can't move out. So any normal access before the
> acquire
> can move to after the acquire, but not the other way around. Any normal
> access after the release can be moved to before the release, but not
> the
> other way around.
> 
> So:
> 
>    volatile_v = 1;
>    non_volatile_x = 42;
> 
> can be reordered; but
> 
>    non_volatile_x = 42;
>    volatile_v = 1;
> 
> can not.
> 
> David
> 
> > Thanks and Regards
> > Yan Cheng CHEOK
> >
> >
> > --- On Mon, 2/7/11, David Holmes <davidcholmes at aapt.net.au> wrote:
> >
> > > From: David Holmes <davidcholmes at aapt.net.au>
> > > Subject: RE: [concurrency-interest] Using a volatile variable
> > as a "guard"
> > > To: "Yan Cheng CHEOK" <yccheok at yahoo.com>,
> > concurrency-interest at cs.oswego.edu
> > > Date: Monday, February 7, 2011, 5:28 PM
> > > You need factory to be volatile too
> > > so that the two variables maintain their
> > > respective ordering. Otherwise the write to the factory can
> > > move before the
> > > write to the flag:
> > >
> > >     this.factory = new NuclearFactory();
> > >     this.isNuclearFactory = true;
> > >
> > > and now thread B can get a NuclearFactory but see
> > > isNuclearFactory before it
> > > was set to true.
> > >
> > > There has been a bit of discussion on this recently. The
> > > use a volatile flag
> > > ensures data is visible when needed, but doesn't prevent it
> > > being visible
> > > earlier. In this example you need strict ordering, or
> > > atomicity, to make
> > > sure that a NuclearFactory is only ever seen when
> > > isNuclearfactory is set.
> > >
> > > David Holmes
> > >
> > > > -----Original Message-----
> > > > From: concurrency-interest-bounces at cs.oswego.edu
> > > > [mailto:concurrency-interest-bounces at cs.oswego.edu]On
> > > Behalf Of Yan
> > > > Cheng CHEOK
> > > > Sent: Monday, 7 February 2011 6:25 PM
> > > > To: concurrency-interest at cs.oswego.edu
> > > > Subject: [concurrency-interest] Using a volatile
> > > variable as a "guard"
> > > >
> > > >
> > > > Hello all,
> > > >
> > > > I came across the article "Java theory and practice:
> > > Fixing the
> > > > Java Memory Model, Part 2", by Brian Goetz.
> > > >
> > > > I hope I understand section "New guarantees for
> > > volatile" correctly.
> > > >
> > > > I try to use a similar technique as Brian Goetz's. My
> > > objective is :
> > > >
> > > > A) Never execute factory's operate member function, if
> > > it is a
> > > > NuclearFactory.
> > > >
> > > > Hence, I try to turn on volatile guard variable
> > > isNuclearFactor,
> > > > before I attempt to construct nuclear factory. This is
> > > different
> > > > from Brian Goetz's.
> > > > Brian Goetz only write to volatile variable, after he
> > > had
> > > > finished constructed configOptions.
> > > >
> > > > I feel the following code should work, based on the
> > > information
> > > > picked from Brian Goetz's article.
> > > >
> > > > ""Under the new memory model, when thread A writes to
> > > a volatile
> > > > variable V, and thread B reads from V, any variable
> > > values that
> > > > were visible to A at the time that V was written are
> > > guaranteed
> > > > now to be visible to B""
> > > >
> > > > when thread A writes to volatile isNuclearFactory, and
> > > thread B
> > > > reads from isNuclearFactory, factory was visible to A
> > > as
> > > > FoodFactory at the time that isNuclearFactory was
> > > written. Hence,
> > > > factory are guranteed now to be visible to B as
> > > FoodFactory too.
> > > >
> > > >
> > > > I hope I am getting this correctly. Or, do I need to
> > > mark factory
> > > > as volatile too?
> > > >
> > > >
> > > > void fun_by_thread_A() {
> > > >     this.isNuclearFactory = true;
> > > >     this.factory = new
> > > NuclearFactory();
> > > > }
> > > >
> > > > void fun_by_thread_B() {
> > > >     Factory _factory =
> > > this.factory;
> > > >     if (this.isNuclearFactory) {
> > > >         // Do not
> > > operate nuclear factory!!!
> > > >         return;
> > > >     }
> > > >     // If out-of-order execution
> > > happens, _factory might
> > > >     // be NuclearFactory
> > > instance.
> > > >     _factory.operate();
> > > > }
> > > >
> > > > Factory factory = new FoodFactory();
> > > > volatile boolean isNuclearFactory = false;
> > > >
> > > > Thanks and Regards
> > > > Yan Cheng CHEOK
> > > >
> > > >
> > > >
> > > > _______________________________________________
> > > > Concurrency-interest mailing list
> > > > Concurrency-interest at cs.oswego.edu
> > > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > > >
> > >
> > >
> >
> >
> >
> >
> 
> 
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest



More information about the Concurrency-interest mailing list