ARM Cortex M7上何时真正需要CLREX?

时间:2018-07-03 20:23:23

标签: arm atomic cortex-m

我在网上发现了几个地方,这些地方指出,每当进入中断例程时,都必须调用CLREX,这是我不理解的。 CLREX状态的文档(添加了编号以方便参考):

  

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

     

(2)使用CLREX指令将紧密耦合的互斥访问监视器返回其开放访问状态。这样就消除了将虚拟存储存储到内存的需求。

     

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

我在这里什么都不懂。

我的印象是,按照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足以保证从多个中断中原子访问地址?即GCC for ARM使用LDREX / STREX编译了所有C11原子函数,但我看不到CLREX在任何地方都被调用。

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

  3. global 记录和 local 记录有什么区别?多核方案是否需要全球记录?

2 个答案:

答案 0 :(得分:4)

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

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。避免了什么“虚拟商店要求”?

如果没有CLREX指令,则有必要使用STREX放弃互斥访问标志,该标志涉及内存事务,因此比需要的速度慢如果您要做的就是清除标志。

3。是多核方案的“全球记录”吗?

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

答案 1 :(得分:1)

实际上,M7上的异常/中断不需要CLREX ,它似乎仅出于兼容性原因而被包括在内。来自documenation (Version c)

  

CLREX支持与其他具有以下功能的ARM Cortex处理器的兼容性:   发生异常时强制存储独占失败   在加载独占指令和匹配存储独占之间   同步操作中的指令。在Cortex-M处理器中,   本地独占访问监视器会自动清除   异常边界,因此使用CLREX的异常处理程序是可选的。

因此,由于Cortex-M处理器在异常/中断进入/退出时清除了本地独占访问标志,因此这将CLREX的大多数(全部?)用例否定。

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

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

更新

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

  

在以下情况下,处理器将删除其独占访问标签:

     
      
  • 它执行CLREX指令。

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

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

  •   
     

在多处理器实现中:

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

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

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

  •