POD类型的原子位操作

时间:2017-06-22 19:19:11

标签: c++ atomic

鉴于以下内容:

#include<atomic>

struct Foo
{
    uint64_t data[1];
};

std::atomic<Foo> bar;

void DoAtomicOr(uint64_t value)
{
    std::atomic_fetch_or(&bar, value);
}

我的编译器抱怨第一个参数的类型不能传递给fetch,因为它的类型不匹配任何已知的重载。我可以将它强制转换为:

std::atomic_fetch_or((std::atomic<uint64_t> *)&bar, value);

但这很容易出错,因为我已经在今天早些时候证明了这一点。有没有更好的方法让编译器意识到他的Pod类型Foo在这里实际上只是一个荣耀的uint64_t

1 个答案:

答案 0 :(得分:2)

Foo不是integral类型,因此您无法使用fetch_or()

一种解决方案是使用data[1](而不是Foo)作为atomic类型:

struct Foo
{
    std::atomic<uint64_t> data[1];
};

Foo bar;

void DoAtomicOr(uint64_t value)
{
    std::atomic_fetch_or(&bar.data[0], value);
}

如果您想保留Foo atomic,可以使用OR操作进行比较和交换:

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