Bill Pugh wrote:
>Rob's example only works if volatiles are 2-way memory barriers.
>Here is how you need to change it to make it work for volatiles that
>have load.acquire and st.release semantics:
>
>
>volatile int vno = 0;
>volatile boolean force;
>int a,b;
>synchronized void inc(int x) {
> int oldVersion = vno;
> vno = oldVersion+1;
> boolean ignore = force; /* Don't allow accesses to be hoisted */
> a += x;
> b += x;
> vno = oldVersion+2;
> }
>/* unsynchronized */
>int prod() {
> int v1 = vno; /* pre-inspect */
> int t1 = a;
> int t2 = b;
> force = false; /* force all accesses to be committed */
> int v2 = vno; /* post-inspect */
> if (v1 == v2 && v1%2 == 0)
> return t1*t2; /* commit */
> else ... /* abort */
> }
...
>Note that no one ever cares about the value stored into the force
>variable. It is just used for establishing memory ordering.
I understand the need for boolean ignore = force in the inc method ---
indeed I mentioned that in the ECOOP paper ---
but I thought that according to the version of Bill's volatile proposal
that I
saw at the time I wrote the ECOOP paper, there was no need for
force = false in the prod method. Adding that statement is
a bit disruptive, since it implies that the "read" methods have
to write to shared memory. The ignore statement in the inc method was
sufficient to guarantee that any reads of a and b were corralled
between the writes of vno. And vno being volatile was sufficient to
corral reads between successive reads of vno. Am I missing something?
Can you give me an example of a case where (assuming force = false
is not included in prod) an execution can both commit and return
the wrong result?
-- Rob------------------------------- JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:32 EDT