ARM Cortex M7 什么时候真正需要 CLREX?

Lou*_*Lou 9 arm atomic cortex-m load-link-store-conditional

我在网上找到了几个地方,其中指出每当进入中断例程时“必须”调用 CLREX,我不明白。CLREX状态的文档(添加编号以便于参考):

(1) 清除执行处理器的本地记录,该记录表明地址已请求独占访问。

(2) 使用该CLREX指令将一个紧密耦合的独占访问监视器返回到其开放访问状态。这消除了对内存的虚拟存储的要求。

(3) 是否CLREX也清除执行处理器的全局记录,即某个地址已请求独占访问,则由实现定义。

我在这里几乎什么都不懂。

我的印象是,按照文档中示例编写一些内容足以保证原子性:

    MOV r1, #0x1                ; load the ‘lock taken’ value
try:                                                       <---\
    LDREX r0, [LockAddr]        ; load the lock value          |
    CMP r0, #0                  ; is the lock free?            |
    STREXEQ r0, r1, [LockAddr]  ; try and claim the lock       |
    CMPEQ r0, #0                ; did this succeed?            |
    BNE try                     ; no - try again   ------------/
    ....                        ; yes - we have the lock
Run Code Online (Sandbox Code Playgroud)
  1. 为什么要清除“本地记录”?我认为LDREX/STREX足以保证从多个中断对地址进行原子访问?即 GCC for ARM 使用LDREX/编译所有 C11 原子函数STREX,我没有看到CLREX在任何地方被调用。

  2. 第二段指的是什么“对虚拟商店的要求”?

  3. 全局记录和本地记录有什么区别?多核场景是否需要全局记录?

coo*_*sed 10

分别回答(和解释)你的三个问题:

1、为什么要清除访问记录?

当强制执行严格的代码嵌套时,例如当您处理中断时,CLREX通常不需要。但是,在某些情况下它很重要。想象一下,您正在为抢占式操作系统内核编写上下文切换,它可以异步挂起正在运行的任务并恢复另一个。现在考虑以下病态情况,涉及使用LDREX和操作相同共享资源的两个相同优先级的任务(A 和 B)STREX

Task A      Task B
  ...
 LDREX
-------------------- context switch
             LDREX
             STREX   (succeeds)
              ...
             LDREX
-------------------- context switch
 STREX               (succeeds, and should not)
  ...
Run Code Online (Sandbox Code Playgroud)

因此上下文切换必须发出 aCLREX来避免这种情况。

2. 避免什么“对虚拟商店的要求”?

如果没有CLREX指令,则有必要使用 aSTREX来放弃独占访问标志,这涉及内存事务,因此如果您想要做的只是清除标志,则它比需要的速度慢。

3. 是多核场景的“全球记录”吗?

是的,如果您使用的是单核机器,则只有一个记录,因为只有一个 CPU。


Gra*_*eme 6

实际上,M7 上的异常/中断不需要它,它似乎只是出于兼容性原因而包含在内CLREX 来自文档(版本 c)

CLREX 能够与其他 ARM Cortex 处理器兼容,如果同步操作中加载独占指令和匹配的存储独占指令之间发生异常,这些处理器必须强制存储独占失败。在 Cortex-M 处理器中,本地独占访问监视器会在异常边界上自动清除,因此使用 CLREX 的异常处理程序是可选的。

因此,由于 Cortex-M 处理器清除异常/中断进入/退出时的本地独占访问标志,这否定了CLREX.

关于你的第三个问题,正如其他人提到的,你认为全局记录用于多核场景是正确的。CLREX根据实现定义对本地/全局标志的影响,多核处理器上可能仍然存在用例。

我可以理解为什么这方面存在混乱,因为 M7 文档的初始版本不包含这些句子(更不用说 ARM 网站上更通用文档的各种其他版本)。即使现在,我什至无法链接到最新版本。该页面默认显示“版本 a”,您必须通过下拉框手动更改版本(希望这将来会改变)。

更新

为了回应评论,提供了一个额外的文档链接。这是手册的一部分,描述了特定说明文档之外的这些说明的用法(并且自第一次修订以来一直存在):

如果出现以下情况,处理器将删除其独占访问标记:

  • 它执行 CLREX 指令。

  • 无论写入是否成功,它都会执行STREX指令。

  • 发生异常。这意味着处理器可以解决不同线程之间的信号量冲突。

在多处理器实现中:

  • 执行 CLREX 指令仅删除处理器的本地独占访问标记。

  • 执行 STREX 指令或异常会删除处理器的本地独占访问标记。

  • 对可共享内存区域执行 STREX 指令还可以删除系统中处理器的全局独占访问标记。