Why do C++11 CAS operations take two pointer parameters?

心不动则不痛 提交于 2020-01-01 07:58:05

问题


Many of the C++11 CAS operations (e.g., atomic_compare_exchange_weak, atomic_compare_exchange_strong) take two pointers and a value, i.e., like this:

bool atomic_compare_exchange(T* pointer, T* expected,       // pseudodeclaration!
                             T desired);

In contrast, the CAS operations from Microsoft, gcc, and Intel all take one pointer and two values:

long InterlockedCompareExchange(long* pointer, long desired,       // Microsoft
                                long expected);

int __sync_bool_compare_and_swap (T* pointer, T expected,          // gcc and
                                  T desired);                      // Intel

Why do the C++11 CAS functions take two pointers and a value instead of what appears to be a more conventional one pointer and two values?


回答1:


The C++11 way is more useful: If the exchange fails, then *expected is updated to the new, current value. That makes it easy to use the function in a loop:

T value = x.load();
T newvalue = frob(value);

while (!atomic_compare_exchange(&x, &value, newvalue))
{
    newvalue = frob(value);
}

With the Microsoft signature, testing whether the operation succeeded is more cumbersome, and ditto for GCC's __sync_type version. With GCC's __sync_bool, you even need to perform another load each time the exchange fails.




回答2:


I don't see why you wouldn't have both though. In my use-case the C++ version is less useful. I want to wait until a variable has some value then I want to set it to a new value.

With GCC instrinsics:

while (!__sync_bool_compare_and_swap(&value, expected, desired)) { }

With C++11:

auto tmp = expected;
while (!value.compare_exchange_weak(tmp,desired)) 
{
  tmp = expected;
}


来源:https://stackoverflow.com/questions/16043723/why-do-c11-cas-operations-take-two-pointer-parameters

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!