assembly – ARM Cortex M3上的Atomic int64_t

前端之家收集整理的这篇文章主要介绍了assembly – ARM Cortex M3上的Atomic int64_t前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
由于我的编译器仍然不支持c 11和std :: atomic,我不得不通过ldrex-strex对手动实现它.

我的问题是:用ldrex和strex“原子地”读取 – 修改 – 写入int64_t的正确方法是什么?

像这样的简单解决方案似乎不起作用(STREXW之一始终返回1):

volatile int64_t value;
int64_t temp;

do
{
    int32_t low = __LDREXW( (uint32_t *)&value );
    int32_t high = __LDREXW( ((uint32_t *)&value)+1 );

    temp = (int64_t)low | ( (int64_t)high<<32);
    temp++;    

} while( __STREXW( temp,(uint32_t *)&value) |  __STREXW( temp>>32,((uint32_t *)&value)+1) );

我找不到关于指向手册中不同地址的几个连续LDREX或STREX指令的任何内容,但在我看来应该允许它.

否则,在某些情况下,多个线程将无法更改两个不同的原子变量.

解决方法

这将无法工作,因为您不能以这种方式嵌套独占.在实现方面,Cortex-M3本地专用监视器甚至不跟踪地址 – the exclusive reservation granule is the entire address space – 因此单独跟踪每个单词的假设已经无效.但是,您甚至不需要考虑任何实现细节,因为该体系结构已明确排除了背对背链路:

If two STREX instructions are executed without an intervening LDREX the second STREX returns a status value of 1. This means that:

  • Every STREX must have a preceding LDREX associated with it in a given thread of execution.
  • It is not necessary for every LDREX to have a subsequent STREX .

由于Cortex-M3(以及一般的ARMv7-M)没有像ARMv7-A那样的ldrexd,你要么必须使用单独的锁来控制对变量的所有访问,要么只是禁用读 – 修改的中断 – 写.如果可能的话,首先重新设计不需要原子64位类型的东西真的会更好,因为你仍然只能在同一个核心上实现相对于其他线程的原子性 – 你根本就不能做任何64从外部代理(如DMA控制器)的角度来看,位操作原子.

原文链接:https://www.f2er.com/java/239870.html

猜你在找的Java相关文章