A breach of immutability due to memory implicit conversions to immutable without synchronisation, maybe??

John Colvin john.loughran.colvin at gmail.com
Wed Nov 14 11:33:02 UTC 2018


On Wednesday, 14 November 2018 at 08:38:55 UTC, Kagamin wrote:
> On Tuesday, 13 November 2018 at 17:18:17 UTC, John Colvin wrote:
>> What - precisely - do you mean by "without acquire-release you 
>> can't meaningfully share data - it simply doesn't reach 
>> another thread"?
>
> The data simply remains in processor cache.
>
>> How would the incrementing of the reference count in 
>> shared_ptr work then?
>
> You mean relaxed order? Looks like llvm has better description 
> for that http://llvm.org/docs/Atomics.html#monotonic it's a 
> synchronization, just weak - synchronizes only one variable, 
> not the entire cache, and why you need full synchronization on 
> decrement - because you may need to run the destructor, which 
> needs the latest state of the object and everything it 
> references.

What relaxed does is roughly: "all relaxed operations on this 
value happen atomically in some order".

int* foo() pure {
     auto ret = new int; // A
     *ret = 3; // B
     return ret;
}

shared immutable(int)* g;

void bar() {
     immutable(int)* d = null;
     while (d is null)
     	d = g.atomicLoad;
     assert(*d == 3); // D
     assert(*d == 3); // E
}

void main() {
     auto t = new Thread(&bar).start();
     immutable(int)* a = foo();
     g.atomicStore!(MemoryOrder.relaxed)(a); // C
     t.join;
}

The relevant ordering restrictions are as follows:

A must happen before B, because `ret` must exist to be used.
A must happen before C, because `a` must exist to be used, which 
cannot exist until `ret` is used.
C must happen before D & E because it's the only way out of the 
while loop.

So we have

A -> C -> D -> E

but B can sit anywhere after A, including between D and E!

To address the "it won't leave the cache" idea which I'm guessing 
is actually meant to be "relaxed atomics make no promises about 
when changes become visible", you should consider whether acq-rel 
actually gives you any more guarantee about that in this case 
(how many iterations of the while loop would you expect?), but 
also that lack of guarantee of timeliness is not the same as a 
guarantee of never.


More information about the Digitalmars-d mailing list