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

John Colvin john.loughran.colvin at gmail.com
Sun Nov 11 19:21:10 UTC 2018


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?


More information about the Digitalmars-d mailing list