Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Atomic bit-wise operations on POD type

Tags:

c++

atomic

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?

like image 664
Michael Dorgan Avatar asked Jun 01 '26 07:06

Michael Dorgan


1 Answers

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));
}
like image 89
LWimsey Avatar answered Jun 02 '26 19:06

LWimsey