1

ARM 提供 LDREX/STREX 以原子地加载/存储值,但我觉得我在这仍然是一个原子操作方面遗漏了一些东西。以下通常是如何增加一。但是,是什么阻止了某些东西在 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
4

1 回答 1

2

ldrex/strex 的工作基于跟踪相对于进程 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 而不是 OKAY(成功与失败),而不是实际跟踪。但是您必须获得该访问权限才能错过缓存层,这意味着它们已关闭,这几乎意味着您没有运行操作系统,因为禁用或不启用缓存很痛苦。

硬件人员被告知您不必支持单处理器的独占访问。ldrex/strex 不能替代 SWP(仍然存在于许多内核中)的一般人群。ldrex/strex 是专门针对多核共享资源的,就是让不同的核基本可以互相通信,共享资源,不是一个核自己竞争。

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

特别是 Linux 社区的软件专注于它是 swp 的替代品,这使得阅读你不必支持它的一个/少数供应商很难,这使得 Linux 无法工作。同时,Linux 内核中存在大量与 arm 相关的错误,尤其是与 arm 相关的错误,移植每个新版本都需要大量工作,因为放置了许多不正确的勘误表和其他解决方法。而且我怀疑许多移植 Linux 的人并没有意识到他们正在创建和/或留在移植中的错误。

简而言之,理论是每个线程都有自己的进程 ID,并且逻辑会跟踪对相关地址和进程 ID 的访问,如果在一个进程 ldrex 和 strex 之间存在访问,那么 strex 将失败你必须从另一个 ldrex 重新开始,这就是它处于循环中的原因。

所以

ldrex id x
...
strex id x  (passes)


ldrex id x
...
ldrex id y
...
strex id x (pass)
...
strex id y (fail)


ldrex id x
... 
ldrex id y
...
strex id y (pass)
...
strex id x (fail)

等等。

显然,逻辑不能存储无限数量的地址和进程 ID 的历史记录,所以很自然,如果......

ldrex id x
...
strex id x

之间有大量的访问。然后,您可能会不时地期待失败。

另请注意,我认为一个或多个 cortex-ms 不支持 arm 逻辑中的 ldrex/strex。

好吧,好吧,例如有这种语言:

Cortex-M3 处理器实现了一个本地独占监视器。处理器内的本地监视器已构建为不保存任何物理地址,而是将任何访问视为与前一个 LDREX 的地址匹配。这意味着实现的独占预留颗粒是整个内存地址范围。

我在其他 cortex-ms 中也看到了这一点。

文档中的更多文本需要思考。

Load-Exclusive 指令总是成功地从内存地址 x 读取一个值。

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

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

注意处理器和/或进程是如何使用的,而不是像线程这样的术语。还要注意关于商店独家而不是一般商店的评论。因此,在进行试验时,您还应该:

ldrex
...
str
...
strex

看看会发生什么。

于 2021-01-08T15:49:31.153 回答