Madeira的总线处理器如何实现非对齐原子操作模拟:一个真实的正确性bug

发布时间:2026/10/4 14:26:42

Madeira的总线处理器如何实现非对齐原子操作模拟:一个真实的正确性bug Madeira的总线处理器如何实现非对齐原子操作模拟一个真实的正确性bug【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/MadeiraMadeira是一个通过 FEX-Emu Wine DXMT 在越狱 iOS 上运行 x86-64 Windows PC 游戏的项目。在支持 32 位游戏的过程中团队踩中了一个真实的正确性 bugD3D9 的设备锁恰好骑在 16 字节边界上每一次LOCK指令都走 FEX 的**拆分校验split CAS**路径来模拟非对齐原子操作——而这条路径如果不加严格串行化计数器会丢更新甚至写出没有任何线程写过的值。 本文就用这个 bug 拆解 ARM64 上的原子操作模拟到底怎么做才对。为什么 32 位游戏会先撞上这个问题x86 架构里LOCK前缀的原子指令如LOCK CMPXCHG、LOCK XADD靠硬件总线锁/缓存行锁保证读-改-写不被打断。但有两个麻烦ARM64 没有等价机制iPhone 的 CPU 无法直接执行 x86 的LOCK语义FEX 必须在翻译层里用软件模拟——这就是文章标题里说的总线处理器部分FEXCore 中的 split CAS 助手函数DoCAS16/32/64位于 FEX 子模块的FEX/FEXCore/Source/Utils/ArchHelpers/Arm64.cpp。32 位 D3D9 的设备锁是非对齐的多个 32 位线程争抢的这块锁字可能落在 16 字节缓存行内的偏移 14处——一个 32 位字横跨两行高 2 字节在这一行低 2 字节在下一行。于是每次对该锁的LOCK CMPXCHG都走拆分开处理的路径。Madeira 之所以会大量触发这条路径是因为它支持未修改的 32 位 Windows 程序WoW64 方案详见 docs/WOW64.md。split CAS 路径非对齐原子操作是怎么模拟的当操作目标跨越 16 字节边界时FEX 的做法是把它拆开获取进程内 split-lock 锁严格模式下是唯一互斥量分别读取跨界的两半如偏移 12 的下半与偏移 16 的上半按 x86 语义完成比较/加法原子地写回两半释放锁竞争失败则重试。这套代码是上游 FEX 原样保留的测试文件 tests/host/check-d3d9-splitlock.py 会把DoCAS16/32/64逐字抽出到宿主机上编译验证覆盖三种真实形状设备锁字偏移 14 的 dword、偏移 12 的 64 位值、偏移 15 的 16 位值。真实的正确性 bug拆分会留下谁都没写过的值问题出在如果两个线程各自只锁定自己那一半、交错地写回缓存行最终会变成A 线程的低半 B 线程的高半——这个组合值没有任何线程写过且更新会丢失。这就是经典的 split-lock 正确性问题表现到游戏里就是 D3D9 设备锁自旋不释放dxmt 诊断日志会打[d3d9-lock-spin]对应MADEIRA_D9_LOCK_DIAG、MADEIRA_D9_LOCK_BACKOFF两个开关。值得强调的一点FEX 的 Arm64.cpp 里没有任何回滚路径——一旦写出撕裂值就无法恢复。所以正确的答案不是写错了再撤销而是根本不允许交错发生。验证脚本会显式断言回滚代码SplitCASRollback必须不存在。修复StrictInProcessSplitLocks 严格进程内互斥正确的解法是让所有split-lock 操作序列化在同一个严格进程内互斥量之下StrictInProcessSplitLocksFEX 的 WOW64 模块对 32 位 guest默认开启该配置且必须在上下文读取配置之前生效测试会断言这行代码的出现顺序对应开关MADEIRA_STRICT_SPLITLOCK默认on完整开关表见 docs/WOW64.md 第 8 节32 位进程的识别与启动路径在 app/Madeira/WineProcessBridge.m从 PE 头判定IMAGE_FILE_HEADER.Machine。四步验证80000 次拆分锁一个数都不能差tests/host/check-d3d9-splitlock.py 是纯宿主机测试不需要 iOS 设备四步走完诊断开关在位dxmt D3D9 前端与 i386 shim 中的诊断开关、日志标签齐全无回滚 默认严格FEX 无 split-lock 回滚路径WOW64 模块在 context 创建前应用严格默认值形状正确设备锁字比较失败时返回当前值且不写入跨界XADD的进位正确跨到高半相邻字节buf[12]、buf[13]、buf[18]、buf[19]分毫未动竞争下精确计数4 线程 × 20000 次拆分LOCK XADD在严格互斥下执行结果恰好等于 80000一个更新都不丢。整个测试以-fsanitizeaddress,undefined编译运行把正确性钉死在可重复验证的断言上。✅获取项目并复现git clone https://gitcode.com/GitHub_Trending/mad/Madeira cd Madeira python3 tests/host/check-d3d9-splitlock.py输出两行PASS即代表设备锁诊断在位、无回滚路径、split CAS 在真实设备锁形状下精确无误。小结关键点结论非对齐原子操作的根因32 位 D3D9 设备锁横跨 16 字节边界每次LOCK都触发 split CAS正确性风险无串行化时可能写出没有任何线程写过的撕裂值且不可回滚正确做法StrictInProcessSplitLocks全局严格互斥32 位 guest 默认开启验证手段逐字抽取 FEXCore 代码 4×20000 并发断言精确计数相关路径docs/WOW64.md、tests/host/check-d3d9-splitlock.py、app/Madeira/WineProcessBridge.m【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/4 14:26:42

CubeFS 集群管理 API 实战:Master 节点运维接口全解析

存储分布式文件系统对象存储云原生 【免费下载链接】cubefs cloud-native distributed storage 项目地址: https://gitcode.com/gh_mirrors/cu/cubefs 点击查看 免费下载 本篇技术指南聚焦 CubeFS 分布式存储系统中资源管理节点 Master 提供的集群管理类 HTTP API&…

2026/10/4 15:31:45

Open-Shell配置全指南:打造高效率的Windows开始菜单

如果你用 Windows 的时间够长,大概率会对 Windows 10/11 那个默认开始菜单有一肚子话想说。磁贴区域要么挤成一团,要么铺满全屏,想找一个程序得先想清楚它被塞进了哪个字母的分类里。Open-Shell(也就是以前的 Classic Shell&#…

2026/10/4 15:31:45

Toeplitz矩阵×FFT:把矩阵向量乘法从O(n²)优化到O(n log n)

第一次被 Toeplitz 矩阵卡住,是几年前跑信道估计仿真的时候。信道矩阵正好是 Toeplitz 结构,当时用最朴素的循环按 O(n) 硬乘,矩阵一上 2048 阶就慢得没法看。后来才搞清楚,这类矩阵天生就是给 FFT 准备的——把 Toeplitz 矩阵塞进…

2026/10/4 15:26:45

QuickBlue:企业级AI应用底座实战指南

1. QuickBlue 不是新玩具,而是企业AI落地的“水电煤”QuickBlue 这个名字刚出来时,我第一反应是——又一个包装精美的PaaS平台?直到去年底帮一家中型制造企业做AI质检系统重构,才真正把它从宣传页里拽进产线环境里跑通。QuickBlue…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑