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

Rubn where at is.this
Sun Nov 11 23:29:13 UTC 2018


On Sunday, 11 November 2018 at 19:21:10 UTC, John Colvin wrote:
> Take a look at this (I think?) supposed-to-be-thread-safe code 
> according to the rules of D:
>
> import std.stdio;
> import core.thread;
> import core.atomic;
>
> int* foo() pure
> {
>     auto ret = new int;
>     *ret = 3;  // MODIFY
>     return ret;
> }
>
> shared immutable(int)* g;
>
> void bar()
> {
>     immutable(int)* d = null;
>     while (d is null)
>     	d = g.atomicLoad;
>     assert(*d == 3); // READ
>     assert(*d == 3); // READ AGAIN
> }
>
> void main()
> {
>     auto t = new Thread(&bar).start();
>     immutable(int)* a = foo();
>     g.atomicStore(a);
>     t.join;
> }
>
> What stops the CPU executing this such that MODIFY happens 
> between READ and READ AGAIN ?
>
> To aid in the thought experiment, imagine if we replace `*ret = 
> 3` with `*ret = longComputation()`? It might help your 
> reasoning about re-ordering if you consider `foo` inlined.
>
> Is implicit conversion to the shared part of immutable actually 
> safe, or does it secretly hide data races?
>
> Another way of putting this:
> Is `ret` secretly shared due to implicit conversion to 
> immutable?


Maybe I'm missing something but:

void bar()
{
     immutable(int)* d = null;
     while (d is null)
     	d = g.atomicLoad;
     assert(*d == 3); // READ
     assert(*d == 3); // READ - these two reads will always be the 
same
}

They will always be the same as what you are changing is the 
pointer. But here you atomicLoad() the pointer. So you will 
always have the same pointer. The value will only change if you 
do another atomicLoad or change the value that the pointer points 
to (which you don't do anywhere in your example).

int* foo() /* pure */
{
     static auto ret = new int; // Note: Static here
     *ret = 3;  // MODIFY
     return ret;
}

You might have a problem if "ret" here is static. But then I 
don't think the function would be pure anymore. Or rather at the 
very least it shouldn't be pure.




More information about the Digitalmars-d mailing list