背景:CCL又名 OpenMCL 是一个非常好的、值得尊敬的、轻量级但相当快的 Common Lisp 编译器。它非常适合 RPi,因为它在 32 位模型上运行,并且不太占用内存。理论上,与较重的 SBCL lisp 编译器不同,它支持 32 位 RPi 上的线程。但它有一个长期存在的互斥错误。
然而,这是一个ARM机器语言问题,而不是一个Lisp问题。我希望 ARM 专家能读到这篇文章并大吃一惊!来自不同背景的时刻。
问题在于,CCL 在 Raspberry Pi 2 和 3(可能还有 4)以及其他 ARM 板上存在致命缺陷:当使用线程和锁定时,它会因内存损坏而失败。螺纹故障多年来一直为人所知。
我相信我进一步将问题隔离为锁定失败:当 CCL 线程获取锁(互斥体)并检查它是否拥有该锁时,有时会发现另一个线程拥有该锁。线程似乎会窃取彼此的锁,这对于垃圾收集等来说是致命的。在我看来,一个核心已控制锁的信息在其他核心自己获取锁之前不会渗透到其他核心(竞争条件)。此错误不会发生在单核 RP 上,例如 Pi Zero。
我已经在这个 GitHub 存储库中探索了这个错误。相关函数是(threadtest2)生成线程、执行锁并检查锁所有权。我最初认为锁定代码可能是缺少DMB指令;DMB“确保独占写入同步到所有处理器”。因此我把DMB指令放在了所有的锁定代码中(但仔细一看,DMB已经在一些地方出现了,所以最初的编译器作者已经想到了这一点)。
具体来说,我将 DMB 放入了从ARM/l0-misc.lisp中调用的无 futex 版本调用的arm-misc.lisp的几乎每个锁定例程中,但没有成功。ARM/l0-misc.lisp 中的低级函数是“%ptr-store-fixnum-conditional”。这不使用 DMB,而是使用 LDREX/STREX 原子更新函数。%get-spin-lock%lock-recursive-lock-ptr
[编辑] 正如用户coredump在下面指出的那样,根据博客和 ARM 文档,DMB 在多核上确实是必要的,尽管对于它应该出现在 STREX 之后还是 LDREX 之前的多少位置存在一些分歧。
显然,我并不是要求任何人诊断这个编译器。我的问题是
这种盗锁行为是否引起了人们的注意?有没有其他人在其他上下文中看到过 ARM 上的锁窃取或竞争条件问题,并且他们找到了解决方案吗?关于 …
我在网上找到了几个地方,其中指出每当进入中断例程时“必须”调用 CLREX,我不明白。CLREX状态的文档(添加编号以便于参考):
(1) 清除执行处理器的本地记录,该记录表明地址已请求独占访问。
(2) 使用该
CLREX指令将一个紧密耦合的独占访问监视器返回到其开放访问状态。这消除了对内存的虚拟存储的要求。(3) 是否
CLREX也清除执行处理器的全局记录,即某个地址已请求独占访问,则由实现定义。
我在这里几乎什么都不懂。
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 - …Run Code Online (Sandbox Code Playgroud) 我开始使用ARM平台(特别是TI TMS570系列).
我有一些关键区域的代码,我不希望发生异常.所以我想在进入区域时保存IRQ和FIR启用的标志,并在退出时恢复它们.
我怎么做?
我在实现AVR系列处理器的关键部分方面经验丰富,您所做的只是禁用中断(当然有内存屏障),执行关键操作,然后重新启用中断:
void my_critical_function()
{
cli(); //Disable interrupts
// Mission critical code here
sei(); //Enable interrupts
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是:
这种简单的方法是否也适用于处理器的ARM体系结构?我听说过处理器在指令和其他黑魔法上做了先见之事,并且主要想知道这些类型的事情是否会对关键部分的这种实现产生问题.
arm ×4
armv7 ×1
atomic ×1
bare-metal ×1
c ×1
common-lisp ×1
cortex-m ×1
interrupt ×1
lisp ×1
load-link-store-conditional ×1
mutex ×1
raspberry-pi ×1
tms570 ×1