On 22.10.18 15:26, Simen Kjærås wrote:
Here's the correct version:

module atomic;

void atomicIncrement(int* p) @system {
     import core.atomic;
     atomicOp!("+=",int,int)(*cast(shared(int)*)p,1);
}

struct Atomic(T) {
     // Should probably mark this shared for extra safety,
     // but it's not strictly necessary
     private T val;
     void opUnary(string op : "++")() shared @trusted {
         atomicIncrement(cast(T*)&val);
     }
}
---------
module unborked;
import atomic;

void main() @safe {
     auto a = new Atomic!int;
     import std.concurrency;
     spawn((shared(Atomic!int)* a){ ++*a; }, a);
     //++i.val; // Cannot access private member
}

Once more, Joe Average Programmer should not be writing the @trusted code in Atomic!T.opUnary - he should be using libraries written by people who have studied the exact issues that make multithreading hard.

--
   Simen

module reborked;
import atomic;

void main()@safe{
    auto a=new Atomic!int;
    import std.concurrency;
    spawn((shared(Atomic!int)* a){ ++*a; }, a);
    ++a.tupleof[0];
}

Reply via email to