I am using a few atomic variables, all unsigned int's, and I wanted to collect them into a structure - effectively a POD. However I also want a constructor because my compiler is not quite c++11 (so I have to define my own constructor to create it with initial values).
So originally I had:
// Names are not the real names - this is just for example std::atomic<int> counter1; std::atomic<int> counter2; std::atomic<int> counter3; And then I was happy to just increment/decrement them as I needed. But then I decided I wanted a few more counters and therefore to put them into a structure:
struct my_counters { int counter1; int counter2; int counter3; // Constructor so that I can init the values I want. my_counters(c1, c2, c3) : counter1(c1), counter2(c2), counter3(c3){;} }; But since I have added a custom constructor this is no longer technically a POD. I was reading other questions regarding this and they where saying that to use std::atomic I need a POD, but other questions I read suggested that the struct needs to be copyable or some such... anyway, I got confused and I want to know if I can safely use my struct my_counters as an atomic type:
std::atomic<my_counters> counters; And then within various threads:
// Are these operations now still atomic (and therefore safe to use across threads): counters.counter1++; counters.counter2--; counters.counter3 += 4;
atomic<my_counters>doesn't have a.counter1member, socounters.counter1++;won't compile. You could implement all 3 modifications with acmpxchgloop, but a 3-intstruct would only be lock-free on a few platforms (like some compilers for x86-64 withlock cmpxchg16b)counter1will contend with threads usingcounter2. (If they're usually all used at the same time, then in the same cache line is good, though.)std::atomic<T>is thatTis TriviallyCopyable, not POD.my_countersis TriviallyCopyable