【问题标题】:ARM: Is LDRX/STRX needed if interrupts are disabled?ARM:如果中断被禁用,是否需要 LDRX/STRX?
【发布时间】:2014-05-28 14:18:33
【问题描述】:

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

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

假设以下示例:

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

如果线程 1 在LDRX 之后被线程 2 中断,会发生什么?线程 1 中的 STRX 是否仍然可以识别地址 a 上的访问权限,或者我是否也必须在线程 2 中使用 LDRXSTRX

【问题讨论】:

  • 如果你的 mainline 使用LDRX/STRX,那么你必须在中断中做同样的事情。 LDRX 保留内存位置。为了让STRX 发出重试信号,使用内存的每个人都必须使用LDRX;你不能混搭访问。 MRC p15, 0, <Rd>, c0, c0, 1 返回 ERG,这是 LDRX/STRX 保留的大小。阅读exclusive montiors
  • 请参阅:LDREX/STREX and cacheERG questionLinux atomic_inc questionLDRX/STRX 的一些概念有点陌生。根据 Linux atomic_inc 问题,我认为您正在考虑 atomiclock-free;在那里查看我投反对票的 wiki 答案。
  • ldrex 和 strex 可以确保在多核处理器中,您的核心代码可以独占访问内存位置,基本上没有其他人在您执行两个单独的事务之间干扰该位置。中断模式等与它无关,要么你需要使用这对指令,要么你不需要。
  • 这个论点我们已经无数次了,ldrex/strex 对于单处理器系统是可选的,在该领域也有不支持的系统。
  • 如果您保留在 arm 逻辑中,则缓存将起作用,如果/当它触及供应商逻辑时,它可能会或可能不会,它可能会遵循一组不同的规则或对规则的解释.一般来说,缓存是打开的,供应商逻辑永远不会看到独占访问,所以它都在 arm 域中。

标签: c multithreading arm atomic interrupt-handling


【解决方案1】:

LDREX/STREX 必须由芯片供应商实施,希望能够符合规范。您可以并且应该获取有关该主题的 arm 文档,在这种情况下,除了 arm arm 和 trms 您还应该获取 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 而不是芯片供应商管理,因此您属于一组规则,如果您的 ldrex/strex 对触及系统内存在 arm 核心之外,那么你就属于供应商规则。

最大的问题是 ARM 的文档在该主题上异常不完整。取决于您阅读的手册和手册中的位置,例如,如果某个其他主控已修改该位置,在您的情况下它是同一主控,因此该位置已被修改,但由于它是您的第二个 strex 应该成功.然后同一个文档说另一个独占读取将监视器重置到不同的地址,如果它是同一地址的另一个独占读取怎么办?

基本上,您的问题是,对于同一地址的两次排他性写入而中间没有排他性读取,第二次是否/应该成功。一个非常好的问题...我看不出在所有 arm 内核中或在整个基于 arm 的芯片世界中都有明确的答案。

ldrex/strex 的底线不是完全特定于 ARM 内核,而是特定于芯片(供应商)。您需要进行实验以确保您可以在该系统(单处理器与否)上使用该指令对。您需要了解 ARM 内核的功能(缓存)以及当该独占访问权限越过内核到达供应商逻辑时会发生什么。对您希望将此代码移植到的每个内核和供应商重复此操作。

【讨论】:

  • 不同寻常的是,上面dwelch的回答中实际上有一些直接不正确的陈述。我已经阅读了相同的文档,并且对它们引起的混乱并不感到惊讶。缓存内存仅使用本地监视器进行管理,不依赖于任何正在实施的全局监视器。在多核系统中,不实现 RAM 的全局监视器实际上违反了架构规范(但已经发生)。 ARM 体系结构参考手册(关于监视器)中称为“实现定义”的位不会影响正确代码的功能。
  • 如果您找不到我所引用的内容,您需要阅读更多文档。 ARM/TRM/AMBA-AXI 文档自相矛盾,并且在海报问题方面是不完整的,特别是对于在 linux 中发现的错误和对这些指令做出的其他假设是不完整的。软件人员认为它们是 swp 的直接替代品,因为 arm 暗示了这一点,但这并不是它们的工作方式。归根结底,它是实现定义的,因为它是某个芯片公司的个人必须实现它。
  • 得到一个满是工程师的房间,你得到一个满是基于文档解释的不同解决方案的房间。
  • 如果您只是缓存该区域,那么您至少在 ARM 的领域内,这仍然会因架构而异,但它应该比供应商更一致。
【解决方案2】:

很抱歉,我只是在 dwelch 中提出“这是错误的”声明,但我昨天没有时间写一个正确的答案。 dwelch 对您的问题的回答是正确的 - 但其中的部分内容至少可能会被误解。

简短的回答是,是的,您需要禁用两个线程的中断或对两个线程都使用 ldrex/strex。

但要明确一点:在所有 v6 或更高版本的 ARM 处理器中都必须支持 ldrex/strex(v6M 微控制器除外)。但是,对于某些 ARMv7 处理器,对 SWP 的支持是可选的。

ldrex/strex 的行为取决于您的 MMU 是否启用以及访问区域配置的内存类型和属性。为了使 ldrex/strex 能够正确运行,某些可能的配置需要向互连或 RAM 控制器添加额外的支持。

整个概念是基于本地和全球独家监视器的想法。如果在标记为不可共享的内存区域上操作(在单处理器配置中),则处理器只需要关注本地监视器。

在多核配置中,相关区域使用在架构上被视为全局监视器的东西进行管理,但仍驻留在多核处理器中,不依赖于外部实现的逻辑。

现在,dwelch 是正确的,因为围绕它的“实现定义”选项太多了。您描述的序列在架构上保证可以工作。该架构不要求 str 将本地(或全局)监视器从独占状态转换为打开状态(尽管在某些实现中可能会这样)。

因此,架构上安全的选项是:

  1. 在两种情况下都使用 ldrex/strex。
  2. 在两种情况下都禁用中断。

【讨论】:

    猜你喜欢
    • 2020-12-07
    • 1970-01-01
    • 2016-11-10
    • 2020-03-24
    • 2016-10-21
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多