Problem #2: Reordering volatile and nonvolatile stores

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem #2: Reordering volatile and nonvolatile stores

alarmnummer
I have a question about the "Problem #2: Reordering volatile and
nonvolatile stores" mentioned in the article by Brian Goetz

http://www-128.ibm.com/developerworks/library/j-jtp02244.html

In the old vm it was allowed to reorden volatile and non volatile
stores and this could lead to non volatile fields that are not set.
But why is this bad? It is the consequence of being a non volatile
field.

The consequence is that a volatile field now has two responsibilities:
1) make sure that a value is read-from/written-to main memory instead of cache
2) prevent reordening with non volatile fields en synchronize them
with main memory before a volatile field is called.

I don't understand why the old behaviour is bad. The mistake of using
a non volatile field was made while information needs to be exchanged
in multiple threads. This sounds acceptable to me, so why is the
second responsibility added? Is this done to make jmm easier to use?
Or are their other reasons I'm missing?
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Problem #2: Reordering volatile and nonvolatile stores

Jeremy Manson-2
Peter Veentjer wrote:
> I have a question about the "Problem #2: Reordering volatile and
> nonvolatile stores" mentioned in the article by Brian Goetz
>
> http://www-128.ibm.com/developerworks/library/j-jtp02244.html
>
> In the old vm it was allowed to reorden volatile and non volatile
> stores and this could lead to non volatile fields that are not set.
> But why is this bad? It is the consequence of being a non volatile
> field.

It is bad because the old behavior was basically useless, on account of
the fact that it didn't support any of the use cases people actually
have for volatiles.  Certainly, the overwhelming majority of the use
cases I've heard of require this behavior.

To pick one use case at random, if you have:

int a = 0;
volatile boolean done = false;

Thread 1:
a = 1;
done = true;

Thread 2:
while (!done)
r1 = a;

Pretty much everyone wants the assignment to a to be seen by the second
thread if the loop finishes.

Now, I suspect you will say that a should also be volatile.  But imagine
what happens if a is a pointer to some enormous data structure, only
some of which you can actually edit.  Should all of the reachable fields
be made volatile, as well?  Ultimately, every field would need to be
tagged volatile, just in case anyone ever wanted to use it in any sort
of multithreaded context.


                                        Jeremy
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Problem #2: Reordering volatile and nonvolatile stores

Joe Bowbeer
In reply to this post by alarmnummer
On 8/22/06, Peter Veentjer <[hidden email]> wrote:

> I have a question about the "Problem #2: Reordering volatile and
> nonvolatile stores" mentioned in the article by Brian Goetz
>
> http://www-128.ibm.com/developerworks/library/j-jtp02244.html
>
> In the old vm it was allowed to reorden volatile and non volatile
> stores and this could lead to non volatile fields that are not set.
> But why is this bad? It is the consequence of being a non volatile
> field.
>
> The consequence is that a volatile field now has two responsibilities:
> 1) make sure that a value is read-from/written-to main memory instead of cache
> 2) prevent reordening with non volatile fields en synchronize them
> with main memory before a volatile field is called.
>
> I don't understand why the old behaviour is bad. The mistake of using
> a non volatile field was made while information needs to be exchanged
> in multiple threads. This sounds acceptable to me, so why is the
> second responsibility added? Is this done to make jmm easier to use?
> Or are their other reasons I'm missing?
>

First of all, the old behavior was never completely specified, or
implemented, so it's hard to compare new with old.

As I understand the current spec, volatile reads and writes are
synchronization actions, similar in some ways to tiny one-statement
synchronized blocks.

To be effective as synchronization actions, it's important that the
rest of the code not move around too much.  Would you think it OK if
code outside of a synchronized block were allowed to jump over the
block?  (That would render ReentrantLock useless.)

Also see http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Problem #2: Reordering volatile and nonvolatile stores

alarmnummer
In reply to this post by Jeremy Manson-2
Hmmm.. that sounds reasonable. Thank you.

On 8/22/06, Jeremy Manson <[hidden email]> wrote:

> Peter Veentjer wrote:
> > I have a question about the "Problem #2: Reordering volatile and
> > nonvolatile stores" mentioned in the article by Brian Goetz
> >
> > http://www-128.ibm.com/developerworks/library/j-jtp02244.html
> >
> > In the old vm it was allowed to reorden volatile and non volatile
> > stores and this could lead to non volatile fields that are not set.
> > But why is this bad? It is the consequence of being a non volatile
> > field.
>
> It is bad because the old behavior was basically useless, on account of
> the fact that it didn't support any of the use cases people actually
> have for volatiles.  Certainly, the overwhelming majority of the use
> cases I've heard of require this behavior.
>
> To pick one use case at random, if you have:
>
> int a = 0;
> volatile boolean done = false;
>
> Thread 1:
> a = 1;
> done = true;
>
> Thread 2:
> while (!done)
> r1 = a;
>
> Pretty much everyone wants the assignment to a to be seen by the second
> thread if the loop finishes.
>
> Now, I suspect you will say that a should also be volatile.  But imagine
> what happens if a is a pointer to some enormous data structure, only
> some of which you can actually edit.  Should all of the reachable fields
> be made volatile, as well?  Ultimately, every field would need to be
> tagged volatile, just in case anyone ever wanted to use it in any sort
> of multithreaded context.
>
>
>                                         Jeremy
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest