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
为什么要清除“本地记录”?我认为 LDREX
/STREX
足以保证从多个中断中原子访问一个地址? IE。 GCC for ARM 使用 LDREX
/STREX
编译所有 C11 原子函数,我没有看到 CLREX
在任何地方被调用。
第二段指的是什么“虚拟商店的要求”?
全局记录和本地记录有什么区别?多核场景需要全局记录吗?
分别回答(并解释)你的三个问题:
1.为什么要清除访问记录?
当强制执行严格的代码嵌套时,例如当您处理中断时,通常不需要 CLREX
。但是,在某些情况下它很重要。假设您正在为抢占式操作系统内核编写上下文切换,它可以异步挂起 运行 任务并恢复另一个任务。现在考虑以下病态情况,涉及两个优先级相同的任务(A 和 B)使用 LDREX
和 STREX
操作相同的共享资源:
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.
我在网上发现了几个地方说每当进入中断例程时“必须”调用 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
为什么要清除“本地记录”?我认为
LDREX
/STREX
足以保证从多个中断中原子访问一个地址? IE。 GCC for ARM 使用LDREX
/STREX
编译所有 C11 原子函数,我没有看到CLREX
在任何地方被调用。第二段指的是什么“虚拟商店的要求”?
全局记录和本地记录有什么区别?多核场景需要全局记录吗?
分别回答(并解释)你的三个问题:
1.为什么要清除访问记录?
当强制执行严格的代码嵌套时,例如当您处理中断时,通常不需要 CLREX
。但是,在某些情况下它很重要。假设您正在为抢占式操作系统内核编写上下文切换,它可以异步挂起 运行 任务并恢复另一个任务。现在考虑以下病态情况,涉及两个优先级相同的任务(A 和 B)使用 LDREX
和 STREX
操作相同的共享资源:
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.