On 22.10.18 12:26, Timon Gehr wrote:
---
module borked;

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

struct Atomic(T){
     private T val;
     void opUnary(string op : "++")() shared @trusted {
         atomicIncrement(cast(T*)&val);
     }
}
void main()@safe{
     Atomic!int i;
     auto a=&[i][0];// was: Atomic!int* a = &i;
     import std.concurrency;
     spawn((shared(Atomic!int)* a){ ++*a; }, a);
     ++i.val; // race
}
---

Obviously, this should have been:

---
module borked;

void atomicIncrement(int*p)@system{
    import core.atomic;
    atomicOp!"+="(*cast(shared(int)*)p,1);
}
struct Atomic(T){
    private T val;
    void opUnary(string op:"++")()shared @trusted{
        atomicIncrement(cast(T*)&val);
    }
}
void main()@safe{
    auto a=new Atomic!int;
    import std.concurrency;
    spawn((shared(Atomic!int)* a){ ++*a; }, a);
    ++a.val; // race
}
---

(I was short on time and had to fix Manu's code because it was not actually compilable.)

Reply via email to