C++ 对标准类型使用原子操作

C++ 对标准类型使用原子操作,c++,gcc,atomic,compare-and-swap,C++,Gcc,Atomic,Compare And Swap,目标:我想实现这个功能: int atomicCAS(int* address, int compare, int val); 是A,但我想在C++中实现它。 它必须与此API兼容,即我不能更改地址的类型 我假设通用硬件,例如amd64,以及通用编译器,例如GCC或Clang P>相应的C++ STL函数,需要一个 STD::原子< /代码>类型,我不确定是否允许我这样做: ((std::atomic<int>&) address)->compare_exchang

目标:我想实现这个功能:

int atomicCAS(int* address, int compare, int val);

是A,但我想在C++中实现它。 它必须与此API兼容,即我不能更改

地址的类型

我假设通用硬件,例如amd64,以及通用编译器,例如GCC或Clang

<> P>相应的C++ STL函数,需要一个<代码> STD::原子< /代码>类型,我不确定是否允许我这样做:
((std::atomic<int>&) address)->compare_exchange_strong(...)
((std::原子地址)->比较交换强(…)

我也可以使用GCC内置函数,但不确定是否有任何警告或什么是一个好的检查来断言这是有效的。

\uuuu sync\u val\u compare\u和uu swap
可能是您正在寻找的

我相信没有可移植的方法来做到这一点,主要是因为在C++中,代码>原子< /代码> s可以用锁实现(或者一般在代码< SigeOf(t)< /COD>!!= <代码> sieof(原子)< /代码>) 正如您所提到的,您可以使用GCC内置。
libstdc++
也使用这些函数来实现
std::atomic
,因此,无论何时需要实现与
std::atomic
方法等效的函数,都可以查看
bits/atomic_base.h

对于
atomic::compare\u exchange\u strong

_GLIBCXX_ALWAYS_INLINE bool
  compare_exchange_strong(__int_type& __i1, __int_type __i2,
              memory_order __m1,
              memory_order __m2) volatile noexcept
  {
     memory_order __b2 = __m2 & __memory_order_mask;
     memory_order __b1 = __m1 & __memory_order_mask;

     __glibcxx_assert(__b2 != memory_order_release);
     __glibcxx_assert(__b2 != memory_order_acq_rel);
     __glibcxx_assert(__b2 <= __b1);

     return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
  }
请注意,
compare
是一个in-out参数,如果失败,它将被当前值
*address
覆盖。
此版本相当于原子:将交换与默认内存顺序进行比较,请参见上。

@JiveDadson:我无法更改地址的类型。它必须与我问题中的功能接口兼容。你应该在问题中说,你愿意使用gcc的非便携、非标准功能。没有提到gcc。@JiveDadson:我不知道。这取决于答案。我当然更喜欢便携式的。但如果这是不可能的,那么下一个最好的事情。但是我提到了GCC,我说“我假设…”。C接口可能是:JivdAdsEng: C接口与C++不兼容。看,谢谢。这就是我已经看到的地方。所以,为了让这成为一个完整的例子,在它前面加上
模板
,并添加
\u M_i
作为第一个参数,对吗?与使用
\uuu glibcxx\u assert
相比,标准
assert
可能更好?然后,理想情况下,我还想添加一个静态断言,它是否对
\uu int\u type
有效?或者
\u原子\u比较\u交换\n
是否仅为其工作的类型定义?另外,
\uu m1
/
\uu m2
的默认参数也不错。
int atomicCAS(int* address, int *compare, int val)
{
    return __atomic_compare_exchange_n(address, compare, val, 0,
                                       __ATOMIC_SEQ_CST,
                                       __ATOMIC_ACQUIRE);
}