Boost logo

Boost :

Subject: Re: [boost] [Atomic] Rationale for preventing copyconstruction/assignment?
From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2013-05-31 04:57:51


On 31/05/13 07:33, Andrey Semashev wrote:
> On Thursday 30 May 2013 23:05:10 Rob Stewart wrote:
>> On May 30, 2013, at 5:34 AM, "Peter Dimov" <lists_at_[hidden]> wrote:
>>> Rob Stewart wrote:
>>>> Assignment is a load and a store, as you note, so it isn't atomic, which
>>>> is the point of an atomic type, after all. Between the load and store,
>>>> the source atomic's value can change, so the copy can be wrong, hence
>>>> Steven's question.>
>>> I don't think that the copy can be wrong, although I may be missing
>>> something. From a cursory inspection, it seems to me that>
>>> a1 = a2;
>>>
>>> and
>>>
>>> r1 = a2;
>>> a1 = r1;
>>>
>>> are equivalent. It's true that in the second case a2's value can change
>>> after the first line, but it can change in the first case after the only
>>> line as well (which corresponds to changing after the second line in the
>>> second case), and the observable effect is the same (except in the
>>> trivial case in which a1 and a2 are the same variable, but that's easily
>>> taken care of).
>> While what you say is true, the two are different from a sequential
>> consistency POV. Since the default for atomics is sequential consistency,
>> such behavior would not be correct.
>
> Frankly, I don't quite understand this. The standard defines sequential
> consistency with regard to a single particular atomic value. I.e. both "a1 =
> a2" and "r1 = a2" must observe the effects of the last modification of a2 that
> happened before the operation. If you imply that some another side effect can
> happen in between "r1 = a2" and "a1 = r1" then that effect doesn't qualify
> that definition and need not be observed.

Suppose a1,a2 are initially zero

Thread 1 then does:

a2=1; //A
++a2; //B
a1=3; //C

r1=a1; //D

Thread 2 does:
a1=a2; //E

If the assignment is atomic and SC then it must fit neatly into the list
of SC ops.

If the SC ordering is E>>A>>B>>C>>D then r1==3.
If the SC ordering is A>>E>>B>>C>>D then r1==3.
If the SC ordering is A>>B>>E>>C>>D then r1==3.
If the SC ordering is A>>B>>C>>E>>D then r1==2.
If the SC ordering is A>>B>>C>>D>>E then r1==3.

If the assignment is split into a read and write then our assignment E
is split into a read (F) and a write (G) which can occupy different
places in our list.

If the SC ordering is F>>A>>B>>C>>G>>D then r1==0.
If the SC ordering is A>>F>>B>>C>>G>>D then r1==1.

Neither of these are valid results if the assignment is a single atomic op.

Since atomic ops covering multiple locations are seriously non-trivial
without a mutex, it is unlikely that assignment would be done as an
atomic op, and the results could therefore be surprising to people,
since this would be inconsistent with the rest of the atomic interface.

Anthony

-- 
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++11 thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk