Given 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 is complaining that the type of the first parameter cannot be passed into the fetch because its type doesn't match any known overloads. I can typecast it to:
std::atomic_fetch_or((std::atomic<uint64_t> *)&bar, value);
But this is error prone as I already proved to myself early today. Is there a better way to get the compiler to realize that he Pod type Foo here is actually just a glorified uint64_t?
Foo is not an integral type and therefore you cannot use fetch_or().
One solution is to use data[1] (instead of Foo) as an atomic type:
struct Foo
{
std::atomic<uint64_t> data[1];
};
Foo bar;
void DoAtomicOr(uint64_t value)
{
std::atomic_fetch_or(&bar.data[0], value);
}
In case you want to keep Foo atomic, you can use a compare-and-swap with an 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));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With