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];
}