[dmd-concurrency] synchronized, shared, and regular methods inside the same class

Sean Kelly sean at invisibleduck.org
Tue Jan 5 10:21:51 PST 2010


On Jan 5, 2010, at 10:14 AM, Kevin Bealer wrote:

> On Mon, Jan 4, 2010 at 6:58 PM, Andrei Alexandrescu <andrei at erdani.com> wrote:
> 
> shared int x;
> ...
> ++x;
> 
> The putative user notices that that doesn't work, so she's like, meh, I'll do this then:
> 
> int y = x;
> ++y;
> x = y;
> 
> And the user remains with this impression that the D compiler is a bit dumb. Of course that doesn't avoid the race condition though. If the user would have to call atomicIncrement(x) that would be clearly an improvement, but even this would be an improvement:
> 
> int y = sharedRead(x);
> ++y;
> sharedWrite(y, x);
> 
> When writing such code the user inevitably hits on the documentation for the two intrinsics, which clearly define their guarantees: only the sequence of sharedRead and sharedWrite is preserved. At that point, inspecting the code and understanding how it works is improved.
> 
> ...
> Andrei 
>  
> Just to clarify, this is still broken, right?  I mean that if two users are calling a method that does this,
> the value of x will only get incremented once if their calls to sharedRead/sharedWrite are interleaved?

Yes.  You either need to call a special hardware instruction (LOCK INC on x86) or use a CAS loop:

void increment( ref shared int x )
{
    int t;
    do {
        t = atomicLoad( x );
    } while( !atomicStoreIf( x, t + 1, t ) );  // atomicStoreIf is a CAS
}



More information about the dmd-concurrency mailing list