InterlockedCompareExchange Android崩溃问题

问题描述 投票:1回答:1

[我正在尝试使用c ++(本机)运行适用于Android的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;
}

现在,即使使用新功能获得相同的值,我在应用程序中也会出现一些引用错误和奇怪的行为,知道吗?

android c++ 64-bit arm64
1个回答
0
投票

[在某些平台上,我猜这就是武装,总线错误通常意味着您具有未对齐的访问权限(在您的情况下,您的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捕获),这样的未对齐原子也不会以预期的方式表现出来,如果它被不同的线程同时访问。

© www.soinside.com 2019 - 2024. All rights reserved.