RE: JavaMemoryModel: SC or Coherence for Volatiles?

From: Yang, Yue (yyang@enterasys.com)
Date: Mon Mar 25 2002 - 13:00:48 EST


Jeremy,

I agree with you that it's unnecessary to include a volatile write into the
previous_t. Since a volatile write w can not bypass a previous volatile
write w', w' must have already been committed when w occurs.

But my main "difficulty" :) is that I'm still not clear what
init/performVolatileWrite does for us.

1) Why must volatile writes be divided in more than one stage to allow
Figure 13 in your paper to happen? As detailed in message
http://www.cs.umd.edu/~pugh/java/memoryModel/archive/1053.html, that seems
to be a legal trace under your simple semantics.

2) In initVolatileWrite, should it read "Assert uncommittedVolatileValue_v =
n/a" instead of "!= n/a"? Don't you want to block a concurrent
initVolatileWrite on the same v?

3) What is readThisVolatile used for?

4) Are you really trying to achieve the relaxation that "there is only a
total order over writes to individual volatile variables" proposed in
Section 8.6.1? Or is the intention somewhat different?

For example, are you going to allow the following?

Initially,
volatile int a = 0;
volatile int b = 0;

T1:
a = 1;
u = b;

T2:
b = 1;
v = a;

Can (u, v) = (0, 0)? (Which should be allowed by the relaxation you proposed
in Section 8.6.1.)

I think only after fully understanding the notation, can we start reasoning
about the implications of the semantics.

Thank you very much for your further clarification.

Jason Yue Yang
Firmware Engineer
Enterasys Networks
Phone:  801-887-9833

-----Original Message-----
From: Jeremy Manson [mailto:jmanson@cs.umd.edu]
Sent: Thursday, March 21, 2002 5:09 PM
To: javamemorymodel@cs.umd.edu
Subject: RE: JavaMemoryModel: SC or Coherence for Volatiles?

Incidentally, I am getting a lot of garbage in your messages, in addition to
the HTML. Is this a MS mail reader thing?

> What I meant was this:
>
> boolean step1 =3D false;
> volatile boolean step2 =3D step3 =3D false;
>
> Thread 1:
> {
> step1 = true;
> step2 = true;
> step3 = true;
> }

> Thread 2:
> {
> r2 = step2;
> r3 = step3;
>
> if(r3 == true)
> {
> r1 = step1;
> // at this point, r1 and r3 are always true,
> // but r2 may not be true. Even though step2 is a volatile
> // that's been assigned before step3.
> }
> }
>

This makes sense to me. In SC, you can have the following behavior (using 1
and 0 for true and false):

PC Thread 1 Thread 2
1 r2 = step2; (r1 = 0, r2 = 0, r3 = 0)
2 step1 = 1; (r1 = 0, r2 = 0, r3 = 0)
3 step2 = 1; (r1 = 0, r2 = 0, r3 = 0)
4 step3 = 1; (r1 = 0, r2 = 0, r3 = 0)
5 r3 = step3; (r1 = 0, r2 = 0, r3 = 1)
6 if(r3 == 1) (r1 = 0, r2 = 0, r3 = 1)
7 r1 = step1; (r1 = 1, r2 = 0, r3 = 1)

That is a perfectly legitimate ordering.

> Maybe SC is too expensive to implement, but I think we should at least
> require a volatile write (release) to commit all previous volatile
> writes together with the previous normal writes so that a volatile
> flag doesn't have a less relaxed semantics than normal flag in this
> regard.

I think I see your difficulty. The fact that we don't include volatile
writes in the previous_t sets may be throwing you off a little. The simple
way to understand volatiles (their "simple semantics", as we put it in the
paper) is that a volatile can have exactly one value at any time. We fudged
that a little for architectures that don't support atomic instructions, but
we can ignore that for the purpose of this discussion.

If we look at the model, we see two successive volatile writes become:

1: initVolatileWrite a = 1;
2: performVolatileWrite a = 1;
3: initVolatileWrite b = 1;
4: performVolatileWrite b = 1;

The variable a and the variable b each has a value associated with it, what
we call its volatileValue. The performVolatileWrite in line 2 sets
volatileValue(a) to be 1. All other values that have ever been associated
with a are now gone. The performVolatileWrite(b) in line 4 now sets
volatileValue(b) to be 1. All other values that have ever been associated
with b are now gone.

Let's say another thread performs a read of b followed by a read of a, after
this write to b has happened. It will see the volatileValue(b), which is 1,
followed by the volatileValue(a), which is also 1. It cannot see any older
value for a. Volatiles thus actually have stronger semantics than normals,
which can see any of a set of possible values.

Does that assuage your difficulty? Or did I miss the point of your
question?

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

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



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