主要观点:在 Guile 3.0.9 的 aarch64 原子处理中发现一个 bug,找到两个解决方案,其中一个较奇怪所以写此文。
关键信息:
- 2024 年 4 月 22 日 12:00 CEST 发现问题。
- 问题与 C 的
atomic_exchange
等效代码有关,Guile 的 JIT 生成的代码有时会丢失写入。 - 第一个补丁用
swpal x0, x0, [x1]
替换,但需有 ARM v8.1 设备;第二个补丁改变cbnz
目标,问题消失。
重要细节: - 最初代码为
mov x16, x0; ldaxr x0, [x1]; stlxr w17, x16, [x1]; cbnz w17, 1b
。 - 第一个补丁代码为
swpal x0, x0, [x1]
。 - 第二个补丁改变
cbnz
目标后代码为mov x16, x0; 1: ldaxr x0, [x1]; stlxr w17, x16, [x1]; cbnz w17, 1b
,此时问题消失,因为分支目标mov
指令时,ldaxr
设置的x0
值被使用,整个操作变为无操作赋值。最后说明 aarch64 原子操作可能很敏感,一个看似不重要的改变会产生明显效果。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。