Say I have the following global variables in my code:
std::atomic<uint32_t> x(...);
std::atomic<uint32_t> y(...);
std::atomic<uint32_t> z(...);
My task is to multiply x and y and then store the result in z:
z = x * y
I'm aware that the naive approach of calling store() and load() on each object is completely wrong:
z.store(x.load() * y.load()); // wrong
This way I'm performing three separate atomic instructions: another thread might slip through and change one of the values in the meantime.
I could opt for a compare-and-swap (CAS) loop, but it would guarantee atomicity only for swapping the old value of z
with the new one (x*y
): I'm still not sure how to perform the whole operation in a single, atomic step.
I'm also aware that wrapping x
, y
and z
inside a struct and make it atomic is not feasible here, as the struct doesn't fit inside a single 64-bit register. The compiler would employ locks under the hood (please correct me if I'm wrong here).
Is this problem solvable only with a mutex?