Re: JavaMemoryModel: Executions I find profoundly troubling

From: Bill Pugh (pugh@cs.umd.edu)
Date: Mon Jul 28 2003 - 11:24:21 EDT


At 2:50 AM -0700 7/28/03, Jerry Schwarz wrote:
>
>That result can arise quite naturally if the compiler transforms Thread 2 to
>
> r1=x
> y=x

Sorry, not legal. One of the key limitations on compilers in a
multithreaded context is that they cannot introduce additional
redundant reads of shared variables, unless it guarantees that the
reads will return the same value. A read of a shared variable into a
local variable needs to be considered an atomic action with just one
value stored into the local.

Consider:
Initially, a = null

Thread 1:
a = "Hello"

Thread 2:
r1 = a
if (r1 != null)
   r2 = r1.hashCode();

The compiler must not be allowed to transform the code for thread 2 to:

Thread 2:
if (a != null)
   r2 = a.hashCode();

In this code, you can get a null pointer execution that isn't
possible in the original code.

>
>What do we say to disallow this outcome? Do you want to disallow
>redundant loads? That is a pretty severe constraint on compilers?

Neither Sarita's model nor mine (nor the original JMM) allows this
transformation. Loading a shared variable into a local variable
should guarantee that the local variable has exactly one value that
cannot be changed by other threads.

>
>>Example 2:
>>Initially, x = 0, y = 0, a[0] = 1, a[1] = 2
>>
>> Thread 1 Thread 2
>> r1 = X r3 = Y
>> a[r1] = 0 X = r3
>> r2 = a[0]
>> Y = r2
>>
>>Troubling execution r1 == r2 == r3 == 1
>>
>>This execution is troubling because in order for r2 to be 1, r1 must
>>have been 1. But r1 could be one only if thread 2 wrote 1 to X. Which
>>could only be true if thread 2 read 1 from Y. Which could only be
>>true if r2 is 1.
>
>
>Transform Thread 1 to
>
> Y=a[0]
> r1 = X
> a[r1] = 0
> r2 = a[0]
> if ( X == 0 ) Y = 0

Sorry, but you can't speculatively perform a write, and then later
write a different corrective value if you determine that the value
written speculatively was incorrect. Neither Sarita's model, my
model, nor the original JMM allow this transformation. Consider:

Initially: x = 0, y = 0

thread 1:
r1 = x
y = r1

Thread 2:
r2 = y

It would be insanely bad to allow the transformation of thread 1 to:

thread 1:
y = 42
r1 = x
if r1 != 42
   y = r1

In addition to the problem with speculative writes, the transformed
code has also duplicated reads.

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



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