我正在Cortex-A9上使用多线程裸机C/Assembler应用程序。

我有一些共享变量,即从多个线程使用的地址。要执行变量值的原子交换,我使用LDRXSTRX。现在我的问题是,即使禁用了中断,在每次访问此变量之一时是否都需要LDRXSTRX

假设以下示例:

  • 线程1使用LDRXSTRX交换地址a的值。
  • 线程2禁用中断,使用常规LDRSTR交换地址a的值,执行其他不应中断的操作,然后再次启用中断。

  • 如果线程2在LDRX之后立即中断线程1,会发生什么情况?线程1中的STRX是否仍然识别出地址a上的访问权,还是我也必须在线程2中使用LDRXSTRX

    最佳答案

    LDREX/STREX是芯片供应商必须实现的产品,希望能达到规范的目的。您可以并且应该获得关于该主题的arm文档,在这种情况下,除了arm arm和trm之外,您还应该获得amba-axi文档。

    所以如果你有

    ldrex thread 1
    interrupt
    ldrex thread 2
    strex thread 2
    return from interrupt
    strex thread 1
    

    在线程2 ldrex和strex之间,该内存位置没有任何修改,因此strex应该可以工作。但是,在线程1 strex和先前的ldrex之间,对该位置(线程2 strex)进行了修改。因此,从理论上讲,这意味着线程1 strex应该会失败,您必须再次尝试线程1 ldrex/strex对,直到它起作用为止。但这完全是设计使然,您需要不断尝试ldrex/strex对,直到成功为止。

    但这是所有实现的定义,因此您必须查看特定的芯片供应商和型号,然后进行修订并进行自己的实验。例如,Linux中的错误是ldrex/strex是一个无限循环,将其应用于不支持ldrex/strex的系统/情况下,您将获得OKAY而不是EXOKAY,而strex将永远失败,因为您陷入其中永远无限循环(永远不知道我怎么知道所有这些,不得不在逻辑级别调试此问题)。

    首先,ARM文档指出,单处理器系统不需要独占访问支持,因此,如果您触摸单核系统上的供应商特定逻辑,则ldrex/strex对可能无法正常工作。如果您的ldrex/strex保留在arm逻辑(L1和可选的L2高速缓存)中,则是否使用单处理器,那么ldrex/strex对由ARM(而不是芯片供应商)管理,因此如果该对涉及系统内存,则属于一组规则在 ARM 核心之外,那么您就属于供应商规则。

    最大的问题是ARM的文档在该主题上异常地不完整。例如,根据阅读哪本手册以及在手册中的不同位置,它说出某个其他母版是否已修改该位置(在您的情况下,该位置是同一母版),因此该位置已被修改,但是由于是您,第二个strex应该会成功。然后,同一文档说另一个互斥读取将监视器重置为另一个地址,那么,如果它是同一地址的另一个互斥读取,该怎么办?

    基本上,您的问题是关于两次对同一地址的互斥写操作,而中间没有互斥读操作,第二次是否成功?一个很好的问题...我看不到在所有臂式内核中或在整个基于臂的芯片世界中都有一个明确的答案。

    ldrex/strex的底线不是完全针对ARM内核,而是特定于芯片(供应商)。您需要进行实验,以确保可以在该系统上使用该指令对(是否使用单处理器)。您需要知道ARM内核的功能(缓存),以及当独占访问超出内核到达供应商逻辑时会发生什么。对要移植此代码的每个核心和供应商重复上述步骤。

    10-06 07:11