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

When is CLREX actually needed on ARM Cortex M7?

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

(1) Clears the local record of the executing processor that an address has had a request for an exclusive access.

(2) Use the CLREX instruction to return a closely-coupled exclusive access monitor to its open-access state. This removes the requirement for a dummy store to memory.

(3) It is implementation-defined whether CLREX also clears the global record of the executing processor that an address has had a request for an exclusive access.

这里我几乎什么都不懂。

我的印象是按照 example in the docs 的方式写一些东西足以保证原子性:

    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
  1. 为什么要清除“本地记录”?我认为 LDREX/STREX 足以保证从多个中断中原子访问一个地址? IE。 GCC for ARM 使用 LDREX/STREX 编译所有 C11 原子函数,我没有看到 CLREX 在任何地方被调用。

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

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

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

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

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

Task A      Task B
  ...
 LDREX
-------------------- context switch
             LDREX
             STREX   (succeeds)
              ...
             LDREX
-------------------- context switch
 STREX               (succeeds, and should not)
  ...

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

2。避免什么'requirement for a dummy store'?

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

3。 'global record'是针对多核场景吗?

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

实际上 CLREX 不需要 exceptions/interrupts 在 M7 上,它似乎只是出于兼容性原因才包含在内。来自 documenation (Version c):

CLREX enables compatibility with other ARM Cortex processors that have to force the failure of the store exclusive if the exception occurs between a load exclusive instruction and the matching store exclusive instruction in a synchronization operation. In Cortex-M processors, the local exclusive access monitor clears automatically on an exception boundary, so exception handlers using CLREX are optional.

因此,由于 Cortex-M 处理器清除了 exception/interrupt entry/exit 上的本地独占访问标志,这否定了 CLREX 的大部分(全部?)用例。

关于你的第三个问题,正如其他人所说,你认为全局记录用于多核场景是正确的。 CLREX 在多核处理器上可能仍有用例,具体取决于实施定义的对 local/global 标志的影响。

我明白为什么会对此产生混淆,因为 M7 文档的初始版本不包含这些句子(更不用说 ARM 网站上更通用的文档的各种其他版本)。即使是现在,我什至无法 link 到最新版本。该页面默认显示 'Version a',您必须通过下拉框手动更改版本(希望将来会更改)。

更新

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

The processor removes its exclusive access tag if:

  • It executes a CLREX instruction.

  • It executes a STREX instruction, regardless of whether the write succeeds.

  • An exception occurs. This means the processor can resolve semaphore conflicts between different threads.

In a multiprocessor implementation:

  • Executing a CLREX instruction removes only the local exclusive access tag for the processor.

  • Executing a STREX instruction, or an exception, removes the local exclusive access tags for the processor.

  • Executing a STREX instruction to a Shareable memory region can also remove the global exclusive access tags for the processor in the system.