POD 类型的原子位操作
Atomic bit-wise operations on POD type
鉴于以下情况:
#include<atomic>
struct Foo
{
uint64_t data[1];
};
std::atomic<Foo> bar;
void DoAtomicOr(uint64_t value)
{
std::atomic_fetch_or(&bar, value);
}
我的编译器抱怨无法将第一个参数的类型传递到提取中,因为它的类型不匹配任何已知的重载。我可以将其转换为:
std::atomic_fetch_or((std::atomic<uint64_t> *)&bar, value);
但这很容易出错,因为我今天早些时候已经向自己证明了这一点。有没有更好的方法让编译器意识到他的 Pod 类型 Foo
这里实际上只是一个美化的 uint64_t
?
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));
}
鉴于以下情况:
#include<atomic>
struct Foo
{
uint64_t data[1];
};
std::atomic<Foo> bar;
void DoAtomicOr(uint64_t value)
{
std::atomic_fetch_or(&bar, value);
}
我的编译器抱怨无法将第一个参数的类型传递到提取中,因为它的类型不匹配任何已知的重载。我可以将其转换为:
std::atomic_fetch_or((std::atomic<uint64_t> *)&bar, value);
但这很容易出错,因为我今天早些时候已经向自己证明了这一点。有没有更好的方法让编译器意识到他的 Pod 类型 Foo
这里实际上只是一个美化的 uint64_t
?
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));
}