Re: JavaMemoryModel: Idiom for safe, unsynchronized reads

From: David F. Bacon (
Date: Mon Jun 28 1999 - 16:31:08 EDT

Before I join the fray, I'll response to Bill's request for
introductions. I'm a Research Staff Member at IBM's Watson Research
Center. I worked on Thin Locks (aka Bacon Bits), which are now the
standard implementation for lightweight synchronization in all of IBM's
JVM's, as well as some others. I'm currently working on a concurrent,
incremental garbage collector for Java running on a weakly ordered
multiprocessor, and more generally on object-oriented language design
and implementation techniques.

Now, unto the breach....

On Mon, 28 Jun 1999 15:50:38 -0400, Bill Pugh wrote:
>I'm not an expect on processor memory models. I know we have some
>people on the mailing list who are. Help us out....
>On what processors can this sequence of events happen? Will the fact
>that processor 1 did a memory barrier help us out?
> Processor 2 has cached the
> contents of address 0x1234
> Processor 1 allocates a new
> object at address 0x1234
> Processor 1 initializes the
> object at address 0x1234
> Processor 1 does a memory
> barrier
> Processor 1 stores 0x1234
> into address 0x5678
> Processor 2 reads address 0x5678,
> gets 0x1234
> Processor 2 reads contents of object at
> address 0x1234 out of stale cache line

You have to consider not only the cache coherency protocol but also
potential instruction reordering by Processor 2. Some architectures
disallow reordering of data-dependent reads. So if the instructions
issued by processor 2 were:

  load r1, 0x5678
  load r2, (r1)

then on such a machine, the memory barrier would be sufficient.
However, if the machine does not provide such a guarantee (as I believe
is the case for the Alpha), then it would be possible for Processor 2 to
speculate that the result of the first load will be 0x1234, and perform
the second load earlier, before the memory barrier executes.

And if the instruction sequence were

  load r1, 0x5678
  load r2, 0x1234

then either type of machine could perform the second load before the
first, since there is no data dependence. To enforce the dependence you
would need a barrier instruction (e.g. isync on PowerPC or
Membar#LoadLoad on SPARC RMO).

Along these lines, there is a potential hole in the JMM in that section
17.1 is ambiguous about whether the rules that apply to "variables"
apply to inherently local objects such as stack variables. However, if
they don't, it is possible to create a scenario in which a write to a
stack variable that occurs syntactically inside of a synchronized block
in fact is performed afterwards, creating a circular dependency between
synchronized methods.

This is the JavaMemoryModel mailing list, managed by Majordomo 1.94.4.

To send a message to the list, email
To send a request to the list, email and put
your request in the body of the message (use the request "help" for help).
For more information, visit

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