如何使用OSAtomicCompareAndSwap32()重构旧的Apple SDK文件,在C++中显示构建警告?

c9x0cxw0  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(89)

我在使用一些较旧的Apple SDK文件时出现了一些构建警告,我正试图重构这些文件以消除警告。我对语法感到困惑,希望有人能帮助解释它。
一个示例调用是OSAtomicCompareAndSwap32(mWriteIndex, (mWriteIndex + 1) & mMask, &mWriteIndex);,您能帮助解释一下(mWriteIndex + 1) & mMask吗?
所有参数都定义为int32_t类型。
我已经尝试使用std::atomic_compare_exchange_strong_explicit,如错误消息所述,但我得到No matching function for call using

std::atomic<int32_t> mReadIndex, mWriteIndex, mFreeIndex;

std::atomic_compare_exchange_strong_explicit(&mWriteIndex, (mWriteIndex + 1) & mMask, &mWriteIndex, std::memory_order_relaxed, std::memory_order_relaxed);

“OSAtomicCompareAndSwap 32”已弃用:在macOS 10.12中首次弃用-使用std::atomic_compare_exchange_strong_explicit(std::memory_order_relaxed)

rt4zxlrg

rt4zxlrg1#

关于:

(mWriteIndex + 1) & mMask

当然,mWriteIndex + 1mWriteIndex加1。
假设mMask是一个只有一些最低有效位的整数,那么& mMask部分是一个计算(mWriteIndex + 1)的模的老技巧,而不必实际进行除法/模运算-例如如果你想计算x % 16,那么x & 0x0F将给予你同样的结果,同时可能使用更少的CPU周期,因为按位AND传统上比divmod操作更快。当然,这个技巧只适用于对2的幂取模。
你所展示的代码很可能是实现了一个无锁循环FIFO队列;在该方案中,圆形阵列的大小将总是被设置为2的幂,特别是为了允许该技巧起作用。
关于将OSAtomicCompareAndSwap32()函数调用升级到其现代/标准C++替代品,我认为您需要这样的东西:

int32_t expectedVal = mWriteIndex.load();
mWriteIndex.compare_exchange_strong(expectedVal, (mWriteIndex + 1) & mMask, std::memory_order_release, std::memory_order_relaxed);

相关问题