Atomic bit operations like POD
Considering the following:
#include<atomic>
struct Foo
{
uint64_t data[1];
};
std::atomic<Foo> bar;
void DoAtomicOr(uint64_t value)
{
std::atomic_fetch_or(&bar, value);
}
My compiler complains that the type of the first parameter cannot be passed to the fetch because its type does not match any known overloads. I can put it like this:
std::atomic_fetch_or((std::atomic<uint64_t> *)&bar, value);
But it is error prone, as I have proven to myself today. Is there a better way to make the compiler realize that the Pod type Foo
here is actually just glorified uint64_t
?
source to share
Foo
is not a type integral
, so you cannot use fetch_or()
.
One solution is to use data[1]
(instead of Foo
) the type atomic
:
struct Foo
{
std::atomic<uint64_t> data[1];
};
Foo bar;
void DoAtomicOr(uint64_t value)
{
std::atomic_fetch_or(&bar.data[0], value);
}
If you want to keep Foo
atomic
, you can use the compare and replace command with the OR operation:
struct Foo
{
uint64_t data[1];
};
std::atomic<Foo> bar;
void DoAtomicOr(uint64_t value)
{
Foo expected = bar.load();
Foo desired;
do {
desired = expected;
desired.data[0] |= value;
} while (!std::atomic_compare_exchange_weak(&bar, &expected, desired));
}
source to share