[concurrency-interest] Volatile array and Wait

David Holmes dholmes at dltech.com.au
Wed Oct 19 14:12:23 EDT 2005


Chris Purcell writes:
> We wish to attach release semantics to our write to b[22]. Any
> preceding writes must be visible to any reader who subsequently
> performs an acquire.

What we want to do is try to ensure that the write of b[22] is visible to a
subsequent read of b[22] - which would happen if the array element itself
were considered volatile. We're not (or the original context wasn't) using
b[22] as a flag to indicate the "availability" of other data - it is b[22]'s
value that we are interested in.

> If b[22] is *followed* by a volatile write/monitor release, there is a
> period of time in which concurrent updates may see the new value of
> b[22] but not any preceding writes despite performing an acquire in
> between: namely, the time between the write to b[22] committing and the
> release barrier.

Correct. You might see the updated value of b[22] even if you don't see
other writes that occurred prior to writing to b[22].

You can also read b[22] after the last write to it, but before the volatile
write makes it visible. So in short there is no way to guarantee a read of
b[22] will see the latest value because there will always be a window
between the write and the "release" in which a read can sneak in.

You can't use volatiles to guarantee an update won't be seen, only to
guarantee that it will be. So if you want to ensure that a group of updates
are seen either entirely or not at all then you need to use locks to prevent
the values from being inspected.

> Unfortunately, if the write to b[22] is *preceded* by a volatile
> write/monitor release, the write to b[22] can be moved before the
> release barrier (either by compiler or hardware) since it is not itself
> volatile; once again there is a period of time in which concurrent
> updates may see the new value of b[22] then do an acquire, yet still
> not see any preceding writes, namely the time between the write to
> b[22] committing and the release barrier.

Preceding the write to b[22] with a volatile write doesn't achieve anything
with respect to the value of b[22]. You need to think about happens-before
rather than thinking about reordering.

> However, if one could precede the write to b[22] with a release barrier
> then a subsequent volatile read of a value on which the write operation
> is dependent, then the write can no longer be reordered before the
> barrier. The read of b should be sufficient for this.
>
> Hence the correct code is:
>
> b = b; // Release barrier
> b[22] = x; // Subsequent acquire barrier followed by dependent write
>
> as I suggested.

"correct" depends on what you think this is achieving. The read of b will
prevent the reordering of the write to b[22] with the write to b. So any
writes preceding the write to b will become visible. *BUT* the write to
b[22] itself is not guaranteed visible - which is what was wanted: the
effect of having volatile array elements.

Of course another point to take away from this is that an array of volatile
elements isn't that useful anyway.

David Holmes



More information about the Concurrency-interest mailing list