Assembly 这是如何保证ARM中的值已自动更新的?

Assembly 这是如何保证ARM中的值已自动更新的?,assembly,arm,atomic,cpu-architecture,load-link-store-conditional,Assembly,Arm,Atomic,Cpu Architecture,Load Link Store Conditional,ARM提供LDREX/STREX以原子方式加载/存储值,但我觉得这仍然是一个原子操作,我缺少了一些东西。以下是增量1的一般方式。然而,是什么阻止某些东西在ADD指令期间抢占,从而使r2不再匹配[r0]中存储的内容 (Assuming r0 is valid and r1 = 1) ADD LDREX r2, [r0] ADDS r2, r2, #1 STREXNE r2, r1, [r0] @ Store 1 if the original [r0] w

ARM提供LDREX/STREX以原子方式加载/存储值,但我觉得这仍然是一个原子操作,我缺少了一些东西。以下是增量1的一般方式。然而,是什么阻止某些东西在ADD指令期间抢占,从而使r2不再匹配[r0]中存储的内容

(Assuming r0 is valid and r1 = 1)

ADD
    LDREX r2, [r0]
    ADDS  r2, r2, #1
    STREXNE r2, r1, [r0]        @ Store 1 if the original [r0] was not -1
    CMPNE r2, #1
    BEQ ADD

ldrex/strex工作的逻辑基础是跟踪与进程id相关的独占访问,这两个进程id都在总线上显示

因此,如果ldrex和strex之间存在访问权限

ldrex process x
strex process x
由于中断或其他原因,逻辑应返回not OK(不正常),strex返回:

1 If the operation fails to update memory.
如文件所述

现在这里的灰色区域是多重的。arm逻辑本身(由arm l1制作的缓存,如果您从他们那里购买了l2)将支持独占访问。有一段时间,arm文档可能仍然存在,如果这是一个单处理器(只实现了一个内核),那么您不必支持独占访问。您可能会发现,非支持只是在总线上返回EXOKAY而不是ok(success vs fail),而不是实际跟踪。但是您必须获得访问权限才能错过缓存层,这意味着它们已关闭,这几乎意味着您没有运行操作系统,因为禁用或不启用缓存是一件痛苦的事情

硬件人员被告知,您不必支持单处理器的独占访问。一般人群认为ldrex/strex不能替代SWP(SWP仍存在于许多岩芯中)。ldrex/strex是专门为多个核心共享资源而设计的,它是为了让不同的核心基本上可以相互对话并共享资源,而不是让一个核心与自己竞争

软件人员在某些地方被告知,他们是SWP的替代者。还有进程id的问题,如果单处理器,这些事务上是否有不同的id?如果是这样,您是如何以及何时设置这些ID的?即使硬件实现为正确支持独占访问和多处理器,如果两个线程共享相同的id,或者该核心上的所有线程共享相同的id,那么它们将相互干扰。这应该是微不足道的测试,虽然与实验

软件,尤其是Linux社区,关注的是它是swp的替代品,这使得阅读《you's not to support》的一家或几家供应商很难做到这一点,这使得Linux无法工作。同时,Linux内核中有大量与arm相关的bug,尤其是,移植每个新版本需要大量工作,因为存在大量未正确完成的勘误表和其他解决方法。我怀疑很多移植Linux的人都没有意识到他们在端口中创建和/或留下的bug

简言之,理论是每个线程都有自己的进程id,逻辑跟踪对所讨论的地址和进程id的访问,如果一个进程ldrex和strex之间存在访问,那么strex将失败,您必须用另一个ldrex重新开始,这就是它处于循环中的原因

所以

等等

显然,逻辑无法存储无限多个地址和进程ID的历史,因此,如果

ldrex id x
...
strex id x
中间有大量的访问。然后,你可以期待一次又一次的失败

还要注意,我认为cortex ms中的一个或多个不支持arm逻辑中的ldrex/strex

好吧,有一种语言,比如:

Cortex-M3处理器实现本地专用监视器。处理器内的本地监视器的构造使其不包含任何物理地址,而是将任何访问视为与先前LDREX的地址匹配。这意味着实现的独占保留颗粒是整个内存地址范围

我在其他皮质-多发性硬化症中也看到了

从文档中获取更多文本以供思考

Load Exclusive指令始终成功地从内存地址x读取值

只有在没有其他处理器或进程执行地址x的最新存储时,相应的存储独占指令才能成功写回内存地址x。存储独占操作返回一个状态位,指示内存写入是否成功

对于不具有shareable属性的内存区域,独占访问指令依赖于本地监视器,该监视器标记处理器从中执行独占加载的任何地址。同一处理器使用存储独占来修改任何地址的任何未中止尝试都保证清除标记

注意处理器和/或进程是如何使用的,而不是像线程这样的术语。还请注意有关“专卖店”而非“一般专卖店”的评论。因此,在进行试验时,您还应:

ldrex
...
str
...
strex

然后查看发生了什么。

当操作被抢占时,代码的行为就像从未发生过一样,
r2
设置为0以指示此情况。然后代码可以再试一次。fuz:或者至少,好像存储从未发生过一样。这两条指令之间的其他指令不会回滚。这应该是
ADDS
而不是
ADD
,这样只有在
[r0]
中的值以前是
-1
时才进行存储吗?否则我不清楚条件应该完成什么。正如代码所示,您正在无条件地存储
1
,而不是
[r0]
中的增量值;
STREXNE
的操作数可以反转,在这种情况下,
CMPNE
可能希望使用
r1
而不是
r2
@Maxthecat:我明白了。正如old_timer指出的那样,在这种情况下会发生的是原始线程根本不存储。
STREXldrex
...
str
...
strex