Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::atomic union

How do I set a union to be atomic using std::atomic? Or do I have to declare the members of the union to be atomic instead?

typedef union {
    int integer;
    float flt;
    double dbl;
    int *intArray;
    float *floatArray;
    unsigned char *byteArray;
} ValueUnion;

class FooClass {
public:
    std::atomic<ValueUnion> value;

}; 

Access to the union gives an error:

foo->value.floatArray = NULL;

error: no member named 'floatArray' in 'std::__1::atomic<ValueUnion>'
                    foo->value.floatArray = NULL;

Do I need to do something like:

typedef union {
    std::atomic<int> integer;
    std::atomic<float> flt;
    std::atomic<double> dbl;
    std::atomic<int*> *intArray;
    std::atomic<float*> *floatArray;
    std::atomic<unsigned char*> *byteArray;
} ValueUnion;

and declare the member variable value to be as below?

class FooClass {
public:
    ValueUnion value;

}; 
like image 394
John Avatar asked Sep 29 '22 21:09

John


1 Answers

It depends what you want to do with it. For example, to store a value into an atomic union:

foo->value = []{ ValueUnion u; u.floatArray = NULL; return u; }();

or

foo->value.store([]{ ValueUnion u; u.floatArray = NULL; return u; }());

If you want to be able to perform lock-free atomic arithmetic (e.g. atomic increment) on the contained values then you will need to go for your second design (a union of atomics).

like image 136
ecatmur Avatar answered Oct 03 '22 00:10

ecatmur