JavaMemoryModel: acquire & releases on volatile variables

From: Bill Pugh (pugh@cs.umd.edu)
Date: Tue Oct 26 1999 - 17:03:17 EDT


There have been a few questions about this, so let me clarify.

This is a place where I propose changing the existing user-level semantics.

Consider the following code:

if (!initialized) {
        set a bunch of fields
        }
read a bunch of fields

Right now, if initialized isn't volatile, this is badly broken. But
under the old semantics, this is broken even if you declare
initialized to be volatile, because memory operations on volatile and
nonvolatile variables can be freely reordered.

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").

This will make the above code fragment work if initialized is
declared as volatile.

When a thread T1 reads a volatile variable v, it must then acquire
all writes seen by all threads who wrote to v up to and including the
thread that wrote the value to v that T1 read.

When a thread T1 is doing an acquire is done on a particular
(volatile) variable (because it just read the variable), I am just
saying that T1 now must see all writes by all threads that have
written to that same volatile variable.

At 6:10 AM -0700 10/26/99, Hudson, Rick wrote:
>Do you mean there is a function "overwritten_v" for each volatile variable
>"v", and that the above two acquire/release formulas hold for this
>variable? For example, for a read/acquire of volatile variable "v", we
>would have the formula:
>
> For each variable v',
> overwritten_t(v') = overwritten_t(v') union overwritten_v(v')
> previous_t(v') = previous_t(v') union previous_v(v')

correct.

>This would occur just prior to the read rather than just after, right? If
>so, perhaps you should say "acquire/read" rather than "read/acquire" (but
>continue to use "write/release").

No. The acquire has to happen _after_ the read, and the release has
to happen _before_ the write.

The reasoning is that if the acquire happened before the read, then
some other thread could write to the variable between the acquire and
the read, which would cause problems. Similarly, if the write
occurred before the release, then another thread could read and
acquire the value between the write and the release.

        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