Re: JavaMemoryModel: acquire & releases on volatile variables

From: Bill Pugh (pugh@cs.umd.edu)
Date: Tue Oct 26 1999 - 18:31:12 EDT


At 2:58 PM -0700 10/26/99, Paul Haahr wrote:
>Bill Pugh wrote
> > I propose changing the semantics so that before writing to a volatile
> > variable, you must flush all writes from registers and cache (a
> > "release") and after reading a volatile variable, you must update
> > registers and cache (an "acquire").
>
>Just to clarify, you mean a release must ``flush all writes from
>registers and cache'' to all variables (and similar for reads), right?
>
>--p

Correct. So, in particular, if Foo.a is not volatile but Foo.b is volatile,
and initially Foo.a = Foo.b = 0, then

Thread 1 Thread 2
Foo.a = 1 y = Foo.b
Foo.b = 1 x = Foo.a

then if y=1, then x must be equal to 1.

At 6:15 PM -0400 10/26/99, Doug Lea wrote:
>Here, forcing volatile to work this way might make it heavier than
>necessary when used in its common legitimate contexts.

If initialized is defined as volatile, this seems to be a reasonable
coding style to me:

if (!initialized) {
        set a bunch of fields
        initialized = true // sorry, forgot this before
        }
read a bunch of fields

Intuitively, if I receive data through a volatile variable from
thread T1, I might expect to see the other writes that T1 performed.

This also makes a number of other idioms work well. For example, it
makes the single and double check idioms work, even without final
fields and special semantics, if the reference to the helped object
is declared as volatile.

Now there is no one right answer, because before Java, no one tried
to define the semantics of volatile. And right now, nobody uses
volatile much in Java. The C++ spec says
        "There is no implementation independent meaning of volatile"

Either choice could work. But I think using the stronger
acquire/release semantics would not impose a significant performance
impact and would make more code have well defined semantics.

>
>Consider instead saying that volatiles are just like regular variables
>except that they are their own monitors. And that read causes
>acquire, but without (necessarily) any locking action, etc.

If you treat reads and writes of a volatile variable as get/set
methods that synchronize on a hidden monitor, then reads and writes
each perform both an acquire and a release. So my proposal is weaker
than synchronizing on a hidden monitor.

        Bill

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:21 EDT