纤程与用户级线程
在 Windows 上,每一个 libSceFiber 纤程都是真实的 Windows 纤程,因此切换会保留客户机寄存器和客户机栈。用户级线程经由同一条 pthread 路径启动。
仓库笔记截至 2026年10月10日
为什么纤程不能是空操作
客户机代码作为原生机器码运行。一次纤程切换必须恢复精确的寄存器和精确的栈,主机栈帧和客户机栈帧混在那条栈上。若 sceFiberSwitch 不切换就返回成功,游戏会在错误的栈上继续,两边都会被破坏。
PS5PCEM 用一个 Windows 纤程支撑每一个已初始化的客户机纤程。sceFiberRun、sceFiberSwitch 和 sceFiberReturnToThread 使用这套机制。调用 sceFiberRun 的线程是根纤程。公开的 128 字节 SceFiber 记录保存 ABI 签名、状态、入口参数、名称,以及调用者提供的上下文范围。
栈属于谁
游戏提供一块上下文缓冲区,这块缓冲区被记在 ABI 对象里。实际的栈归 Windows 所有。把游戏的缓冲区当作原生 Windows 栈来用,会跳过操作系统所要求的保护页和展开簿记。固件记录所期望的最小上下文仍然会检查,一并检查的还有对齐以及起始和结束签名。
sceFiberGetSelf、终结、跨线程所有权检查和运行时重置都已实现。这个后端存在于 Windows x86-64 原生执行目标上。其他主机可以构建模拟器的其余部分,这条切换路径在那里不可用。
用户级线程
libSceUlt 的初始化和终结会成功,以便游戏的作业系统能够启动。运行时、等待队列、队列数据池、互斥量、信号量和队列按游戏所分配的对象保存主机侧状态。工作项本身经由现有的 pthread 路径启动。工作区大小查询返回这些创建操作所期望的对齐大小。
内核 user-edge 事件队列与 pthread 同步共享同一种感知序列的等待。VideoOut 过滤器 -13 和图形过滤器 -14 搭在这条队列上,并保留每次注册的标识符和用户数据。ULT 是调度粘合层。它不增加第二套 CPU 模拟器。
已经实现的部分
- 供 sceFiberRun、sceFiberSwitch 和 sceFiberReturnToThread 使用的 Windows 纤程。
- ABI 签名、所有权检查,以及带保护页的、由主机拥有的栈。
- ULT 的初始化、队列、互斥量、信号量,以及由 pthread 支撑的工作项。
- 与 VideoOut 和图形完成共享的 user-edge 事件队列。
尚未实现的部分
- 纤程切换存在于 Windows x86-64。其他主机操作系统不会原生运行客户机代码。
- 纤程不是可抢占调度的硬件线程。
- ULT 没有为工作体实现单独的解释器。
相关机制
这些页面说明什么