[cpp-threads] Visibility question
Peter Dimov
pdimov at mmltd.net
Wed Aug 2 00:10:50 BST 2006
Boehm, Hans wrote:
> Clark brought up the following interesting question that I couldn't
> immediately answer. I think I now have the answer, but I thought I
> would post it here to make sure we agree.
>
> The question is whether "raw", i.e. unordered, atomic operations
> should contribute to the happens-before relation.
>
> As a particular example of what I mean, consider (x,y,z atomic, w
> ordinary, everything initially zero):
>
> Thread 1:
> w = 1; // ordinary store
> y.fetch_add<ordered>(1); // ordered atomic; orders
> everything within thread
> x.store<raw>(1);
>
> Thread 2:
> r2 = x.load<raw>();
> z.fetch_add<ordered>(1); // ordered atomic; orders
> everything within thread; different variable
> if (r2) r1 = w; // ordinary load
>
> Is there a data race on w?
I believe that the answer should be "no", in the above and in the following:
T1:
w = 1;
fence();
x.store<raw>(1);
T2:
r2 = x.load<raw>();
fence();
if (r2) r1 = w; // ordinary load
which is, in turn, a different (potentially less efficient) reformulation of
T1:
w = 1;
x.store<release>(1);
T2:
r2 = x.load<acquire>();
if (r2) r1 = w; // ordinary load
and this is plain as day. :-)
> Thinking about this example a bit more. I'm not 100% comfortable with
> either answer. With the synchronization edge, it's clear that ordered
> atomic updates are not equivalent to the nonatomic version, even if
> they operate on thread-private data. That's ugly, though probably
> not a showstopper for C++.
Since an <ordered> atomic is a superset of fence(), it seems reasonable (to
me) for it to not be equivalent to an ordinary op even when operating on
private data.
More information about the cpp-threads
mailing list