原子 compare_exchange,但基于设置的标志,而不是相等?
Atomic compare_exchange, but based on flag being set, rather than equality?
std::atomic 提供 compare_exchange_strong(a,b) 测试基础值当前是否为 "a",如果是,则将其替换为 "b",在 atomic/thread-safe 方式。
是否有任何无锁的、原子的方式来执行类似的操作,但不是测试与 "b" 的相等性,而是将 "b" 视为标志,如果出现则执行替换基础值是否设置了该标志?
所以原则上,类似于
bool compare_exchange_flags(std::atomic<int>& underlying, int& flag, int replacement)
{
auto tmp = underlying.load();
if((tmp & flag) == flag) // only perform replacement if flag is set
{
flag = tmp; // emulate compare_exchange_strong, where expected value is replaced with actual value
underlying = replacement;
return true;
} else {
flag = underlying.load();
return false;
}
}
只有在一个版本中……好吧,实际上可以工作;)(当然,以上操作根本不是原子的)
谢谢!
对于上下文:这是针对消息总线的。此总线具有与某些状态(例如可读、可写)关联的内存区域。
每个状态都需要用一些标志来增强——例如,一个状态可以只是 "WRITEABLE",这意味着写入者可以自由地将数据写入片段(读者当前正在旋转/忙于轮询)。
或者它可以是"WRITEABLE | SIGNALED",这意味着写入者可以获取此内存进行写入,但需要在写入数据后触发事件以通知读者。
所以(从概念上讲,这不是实际代码 - 只是为了粗略演示)类似
void send(...)
{
auto expected = WRITEABLE;
if(compare_exchange_flags(status, expected, WRITE_RESERVED))
{
// ... write data ...
status = WRITTEN;
if((expected & SIGNALED) = SIGNALED)
wakeUpReaders();
} else {
tryAnotherRegion();
}
}
没有这样的说明。但是这种操作通常是通过一个循环来执行的,该循环尝试在值具有标志时交换值:
bool replace_if_flag(std::atomic<int>& underlying, int flag, int replacement){
auto tmp = underlying.load();
if(!(tmp & flag)) return false;
while (!underlying.compare_exchange_weak(tmp,replacement)){
if(!(tmp & flag)) return false;
}
return true;
}
std::atomic 提供 compare_exchange_strong(a,b) 测试基础值当前是否为 "a",如果是,则将其替换为 "b",在 atomic/thread-safe 方式。
是否有任何无锁的、原子的方式来执行类似的操作,但不是测试与 "b" 的相等性,而是将 "b" 视为标志,如果出现则执行替换基础值是否设置了该标志?
所以原则上,类似于
bool compare_exchange_flags(std::atomic<int>& underlying, int& flag, int replacement)
{
auto tmp = underlying.load();
if((tmp & flag) == flag) // only perform replacement if flag is set
{
flag = tmp; // emulate compare_exchange_strong, where expected value is replaced with actual value
underlying = replacement;
return true;
} else {
flag = underlying.load();
return false;
}
}
只有在一个版本中……好吧,实际上可以工作;)(当然,以上操作根本不是原子的)
谢谢!
对于上下文:这是针对消息总线的。此总线具有与某些状态(例如可读、可写)关联的内存区域。
每个状态都需要用一些标志来增强——例如,一个状态可以只是 "WRITEABLE",这意味着写入者可以自由地将数据写入片段(读者当前正在旋转/忙于轮询)。 或者它可以是"WRITEABLE | SIGNALED",这意味着写入者可以获取此内存进行写入,但需要在写入数据后触发事件以通知读者。
所以(从概念上讲,这不是实际代码 - 只是为了粗略演示)类似
void send(...)
{
auto expected = WRITEABLE;
if(compare_exchange_flags(status, expected, WRITE_RESERVED))
{
// ... write data ...
status = WRITTEN;
if((expected & SIGNALED) = SIGNALED)
wakeUpReaders();
} else {
tryAnotherRegion();
}
}
没有这样的说明。但是这种操作通常是通过一个循环来执行的,该循环尝试在值具有标志时交换值:
bool replace_if_flag(std::atomic<int>& underlying, int flag, int replacement){
auto tmp = underlying.load();
if(!(tmp & flag)) return false;
while (!underlying.compare_exchange_weak(tmp,replacement)){
if(!(tmp & flag)) return false;
}
return true;
}