InterlockedCompareExchange Android 崩溃问题
InterlockedCompareExchange Android crash issue
我正在尝试 运行 一个用于 android 的应用程序,用于使用 c++(本机)的 64 位处理器,当我执行这些功能时,我遇到了崩溃问题(总线错误)
// returns the resulting incremented value
#define InterlockedIncrement(pInt) __sync_add_and_fetch(pInt, 1)
// returns the resulting decremented value
#define InterlockedDecrement(pInt) __sync_sub_and_fetch(pInt, 1)
// returns the initial value
#define InterlockedExchangeAdd(pInt,nAdd) __sync_fetch_and_add(pInt,nAdd)
// returns the initial value of the pInt parameter.
#define InterlockedCompareExchange(pInt,nValue,nOldValue) __sync_val_compare_and_swap(pInt,nOldValue,nValue)
我阅读了一些关于这些函数的信息,它似乎只适用于 32 位处理器
我试过这样改调用
#include <atomic>
#include <iostream>
inline BOOL InterlockedCompareExchange(volatile INT* pInt, INT nValue, INT nOldValue)
{
std::atomic<INT> ai;
ai = *pInt;
return ai.compare_exchange_strong(nOldValue, nValue,
std::memory_order_release,
std::memory_order_relaxed);
}
inline LONG InterlockedExchange(volatile LONG* pInt, LONG nValue)
{
std::atomic<LONG> ai;
LONG nOldValue;
ai = *pInt;
nOldValue = *pInt;
while (!ai.compare_exchange_strong(nOldValue, nValue,
std::memory_order_release,
std::memory_order_relaxed));
*pInt = nValue;
return nValue;
}
inline LONG InterlockedIncrement(volatile LONG* pInt)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_add(1, std::memory_order_relaxed);
*pInt = ai;
return ai;
}
inline LONG InterlockedDecrement(volatile LONG* pInt)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_sub(1, std::memory_order_relaxed);
if (ai < 0)
ai = 0;
*pInt = ai;
return ai;
}
inline LONG InterlockedExchangeAdd(volatile LONG* pInt, LONG nValue)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_add(nValue, std::memory_order_relaxed);
if (ai < 0)
ai = 0;
*pInt = ai;
return ai;
}
现在,即使我使用我的新函数获得了相同的值,我的应用程序中的引用和奇怪的行为也出现了一些错误,知道吗?
在某些平台上,我猜 arm 上就是这种情况,总线错误通常意味着您有未对齐的访问(在您的情况下,您的原子 32 位或 64 位整数变量之一不是分别在 4 或 8 字节边界对齐。)
例如,这里是显式未对齐的原子访问:
#include <atomic>
#include <string.h>
int main()
{
char buf[16];
memset( buf, 0, sizeof(buf) );
std::atomic<int> * pi = (std::atomic<int> *)(((intptr_t)buf & ~3) + 5);
pi->fetch_add(1);
return 0;
}
即使像这样的代码似乎可以工作(即不会陷入 SIGBUS 或 SIGSEGV),如果不同线程同时访问这种未对齐的原子,它也不会以预期的方式运行。
我正在尝试 运行 一个用于 android 的应用程序,用于使用 c++(本机)的 64 位处理器,当我执行这些功能时,我遇到了崩溃问题(总线错误)
// returns the resulting incremented value
#define InterlockedIncrement(pInt) __sync_add_and_fetch(pInt, 1)
// returns the resulting decremented value
#define InterlockedDecrement(pInt) __sync_sub_and_fetch(pInt, 1)
// returns the initial value
#define InterlockedExchangeAdd(pInt,nAdd) __sync_fetch_and_add(pInt,nAdd)
// returns the initial value of the pInt parameter.
#define InterlockedCompareExchange(pInt,nValue,nOldValue) __sync_val_compare_and_swap(pInt,nOldValue,nValue)
我阅读了一些关于这些函数的信息,它似乎只适用于 32 位处理器
我试过这样改调用
#include <atomic>
#include <iostream>
inline BOOL InterlockedCompareExchange(volatile INT* pInt, INT nValue, INT nOldValue)
{
std::atomic<INT> ai;
ai = *pInt;
return ai.compare_exchange_strong(nOldValue, nValue,
std::memory_order_release,
std::memory_order_relaxed);
}
inline LONG InterlockedExchange(volatile LONG* pInt, LONG nValue)
{
std::atomic<LONG> ai;
LONG nOldValue;
ai = *pInt;
nOldValue = *pInt;
while (!ai.compare_exchange_strong(nOldValue, nValue,
std::memory_order_release,
std::memory_order_relaxed));
*pInt = nValue;
return nValue;
}
inline LONG InterlockedIncrement(volatile LONG* pInt)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_add(1, std::memory_order_relaxed);
*pInt = ai;
return ai;
}
inline LONG InterlockedDecrement(volatile LONG* pInt)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_sub(1, std::memory_order_relaxed);
if (ai < 0)
ai = 0;
*pInt = ai;
return ai;
}
inline LONG InterlockedExchangeAdd(volatile LONG* pInt, LONG nValue)
{
std::atomic<LONG> ai;
ai = *pInt;
ai.fetch_add(nValue, std::memory_order_relaxed);
if (ai < 0)
ai = 0;
*pInt = ai;
return ai;
}
现在,即使我使用我的新函数获得了相同的值,我的应用程序中的引用和奇怪的行为也出现了一些错误,知道吗?
在某些平台上,我猜 arm 上就是这种情况,总线错误通常意味着您有未对齐的访问(在您的情况下,您的原子 32 位或 64 位整数变量之一不是分别在 4 或 8 字节边界对齐。)
例如,这里是显式未对齐的原子访问:
#include <atomic>
#include <string.h>
int main()
{
char buf[16];
memset( buf, 0, sizeof(buf) );
std::atomic<int> * pi = (std::atomic<int> *)(((intptr_t)buf & ~3) + 5);
pi->fetch_add(1);
return 0;
}
即使像这样的代码似乎可以工作(即不会陷入 SIGBUS 或 SIGSEGV),如果不同线程同时访问这种未对齐的原子,它也不会以预期的方式运行。