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

?

+3


source to share


1 answer


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));
}

      

+2


source







All Articles