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

Sean Kelly sean at invisibleduck.org
Tue Jan 5 17:08:12 PST 2010


On Jan 5, 2010, at 4:37 PM, Kevin Bealer wrote:

> I read through a few papers on hazard pointers, and I still only know enough gun safety to know that the gun is always loaded.  But I can't help but ask...
>  
> What if this code:
>  
> void methodName(ref shared int a)
> {
>     do_stuff();
>  
>     int a1 = borrowShared(a);
>  
>     auto x = computeX(a1);
>     auto y = computeY(a1);
>     auto z = computeZ(a1);
>     int xyz = combine(x, y, z);
>  
>     returnShared(a, xyz);
>  
>     more_stuff();
> }

Strangely enough, this is basically how LL/SC (Load-Linked/Store-Conditional) works.  It's the alternative to CAS that you'll find in some hardware (like SPARC), and I crafted atomicStoreIf() to work as a wrapper for either.

> Was converted to this (borrowing Sean's example):
>  
> void methodName( ref shared int a )
> {
>    do_stuff();
> 
>    int temp1;
>    do {
>        int a1 = temp1 = a;
>  
>        auto x = computeX(a1);
>        auto y = computeY(a1);
>        auto z = computeZ(a1);
>        a1 = combine(x, y, z);
>       
>    } while( !atomicStoreIf( a, a1, temp1 ) );  // atomicStoreIf is a CAS
>    more_stuff();
> }
> It would only work for single variable modifications of course, and if computeX,Y,Z is slow, it is probably pointless or a live-lock. 

You could use a secondary value as a primitive lock, if you wanted to modify more than one variable.  But at that point you may as well just use a mutex in most cases.

> The user would need to understand that this is really a loop, so maybe a different syntax is needed:
>  
> void methodName(ref shared int a)
> {
>     do_stuff();
>  
>     bool quit = false;
>    
>     forshare(a; a1; ! quit) {
>         auto x = computeX(a1);
>         auto y = computeY(a1);
>         auto z = computeZ(a1);
>         quit = /* iteration count test or something */;
>         a1 = combine(x, y, z);
>     }
>  
>     more_stuff();
> }
>  
> I included the quit concept as an optional feature to remind users that this might live-lock; they could of course say "if (...) break" at any time as well.
>  
> (I'm sure there are some critics who will say that putting easy to reach lock-free algorithm primitives next to simple to use language features is like selling rubber snakes and real snakes from the same bin.)

From where current research is going, I think it's more likely that this form of lock-free programming will largely disappear before too terribly long.  So I'd be disinclined to add language features specifically intended to make it more usable.  The nice thing about "shared" is that its real purpose is to denote visibility, so the lock-free stuff is added almost as a side-effect.  If things were to change in the industry later on, the language may not have to change too much to adapt.


More information about the dmd-concurrency mailing list