我阅读了以下文档:ARM的Barrier_Litmus_Tests_and_Cookbook .
第7.2节显示了获取互斥锁/信号量的代码 .
Loop
LDREX R5, [R1] ; read lock
CMP R5, #0 ; check if 0
STREXEQ R5, R0, [R1] ; attempt to store new value
CMPEQ R5, #0 ; test if store suceeded
BNE Loop ; retry if not
DMB
LDREX指令请求对存储器地址进行独占访问 . 如果处理器具有独占访问权限,则仅使用STREX写入成功 . 它们使用DMB指令确保独占写入与所有处理器同步 .
我有一个小问题 . 假设处理器具有对内存地址的独占访问权并将其锁定 . 完成STREX指令后,将删除独占访问 . 从现在开始,其他处理器可以访问此内存 . 但是,写入仍然在处理器的缓存中,直到DMB完成 . 如果另一个处理器在第一个处理器已锁定但尚未同步到RAM时尝试获取对锁的访问权限,会发生什么情况 . 存储器地址不是唯一地锁定到第一个处理器,但写入没有完成 .
任何人都可以解释,为什么这确实有效并且是安全的 . 我有我的问题 .
2 回答
我认为你过度复杂了 . 看看amba / axi规范(以及你在哪里找到了多核心皮质-m4?) . ldrex / strex用于在多处理器芯片中的处理器之间共享资源 . 他们一段时间以来被错误地用于其他事情 . 不幸的是,ARM在正确记录所有这些方面做得非常糟糕 .
ldr的独有部分是processorid和地址(范围)保存在表中 . 当strex发生时,检查该地址(范围)的processorid是否与EXOKAY匹配,如果不是OKAY则不进行存储 . Strex没有清除任何东西,他们有趣地拥有这个clrex指令,我假设将processorid设置为某个不会命中的值,或者取决于他们如何构建表,他们释放了一个表项 .
我可以在写完之后尝试这个,但你可以轻松ldrex然后strex然后strex,相当肯定我已经在全尺寸武器上完成int,将尝试在cortex-m4 ldrex,strex,strex,clrex,strex上看看是什么发生 .
在单处理器系统中,ldrex / strex预计可以在ARM的逻辑中工作,但芯片供应商不需要支持它,可能只是返回OKAY(而不是EXOKAY) . L1当然也可能是L2是超出芯片供应商的臂逻辑 . (皮质有没有l2?) . 通常情况下,您不必担心会遇到芯片供应商代码,如果不能无限期地运行很长时间,您可以长时间运行,因为您将保留其中一个缓存 . 例如,在Linux中禁用这两个缓存是一个皇家PITA,它们可能会让它看起来像是一个编译时选项,但是深入挖掘并看到现实 . 只有一个处理器,您如何获得不同的处理器ID?
在多处理器芯片中,芯片供应商应该在缓存之外正确支持它,如果你甚至可以通过独占访问,如何正常使用ldrex / strex,你最有可能在你的L1缓存中,永远不会得到暴露于芯片供应商提供的内容,但如果你在两者之间中断并且你很可能被L2保存,就会发生这种情况 . 在这种情况下,芯片中有多个处理器ID是有意义的,因为有多个处理器 .
这很好
m7 trm也说了同样的话 .
没有多个核心怎么可能/会产生不同的ID?文档使用术语processorid来指示正在使用哪个处理器 . 皮质中有多少个处理器?也许它在其他地方使用不同的字符串/名称记录,但此时我不知道如何生成cortex-m中的processorid并且是单处理器是不是有多个?我无法访问核心以确定 .
因此,即使逻辑不支持每地址独占访问,他们也没有说他们没有检查处理器ID,他们只是考虑对标记为共享的内存的所有strex访问与最后一个ldrex的处理器ID进行检查,而与其地址无关 .
编辑
生产环境
所以看起来他们在这里做的是在ldrex独立于地址后传递的下一个strex . 所以使用你的术语strex“清除锁定” .
请注意,在ldrex和strex之间放置clrex确实会使strex失败 .
没有击中相同的地址并不重要一个ldrex到一个strex
打开数据缓存并没有改变结果 .
测试功能:
与大哥ARM不同:
strex幸存下来之间的非独占访问,至少根据你发布的非独家商店应该破坏的文件先前的ldrex(在armv7-a上) .
注意以上是在cortex-m4 r0p1 CPUID 0x410FC241上
这是安全的,因为芯片设计师使其安全 . Test_and_Set指令的全部内容将由操作系统用于semaphone和mutex命令 . 在多核/多处理器环境中,除了内置的汇编命令之外,没有其他方法可以准确地实现此功能 .