RFC-0142:zx_thread_legacy_yield

RFC-0142:zx_thread_legacy_yield
状态已接受
区域
  • 内核
说明

引入了专用于 yield 的系统调用。

Gerrit 更改
作者
审核人
提交日期(年-月-日)2021-11-29
审核日期(年-月-日)2021-10-13

摘要

我们建议添加一个新的系统调用 zx_thread_legacy_yield,该调用会导致调用线程将 CPU 让出给另一个等待线程。此外,当截止期限等于零时,我们会移除 zx_nanosleep 的特殊情况。系统调用名称中的 legacy 表示有更合适的机制可用于实现所需行为。

设计初衷

zx_nanosleep 的行为与所有其他系统调用中对截止期限的处理方式不同,即如果截止期限早于当前时间,则立即返回。目前,这是特殊情况,其中截止期限值为零表示让出。

此外,在运行时,无法确定截止期限是故意设为零,还是计算结果。这会简化 zx_nanosleep 的运作方式,减少开发者需要注意的特殊情况。可以手动将截止期限设为零,以使线程让出,也可以在下次唤醒后将其设为零(这意味着立即继续)。

利益相关方

哪些人对此 RFC 的接受与否有利益相关?(此部分为可选部分,但建议填写。)

教员

由 FEC 任命的负责引导此 RFC 完成 RFC 流程的人员。

Reviewers:

咨询了

社交:此设计最初是在设计文档中讨论的。

设计

此提案对 Zircon 系统调用 API 进行了以下更改:

  1. 添加了 zx_thread_legacy_yield
  2. 简化了 zx_nanosleep

其中,zx_thread_legacy_yield 的定义如下:

/// Yields cpu to another waiting thread.
/// `options`: Reserved for future extension. Must be zero.
/// @blocking
zx_status_t zx_thread_legacy_yield(uint32_t options);

在用户空间应用上调用 zx_thread_legacy_yield 时,调用线程会让出 CPU。options 参数稍后可用于引入提示。

使用 options 等于零调用 zx_thread_legacy_yield 保证会返回 ZX_OK

当使用大于单调时钟中时间的截止期限调用 zx_nanosleep 时,系统会将调用线程置于休眠状态,直到达到截止期限(加上空闲时间)为止。另一方面,如果截止期限的值等于或早于单调时钟中的时间,则会立即返回。但是,如果截止期限为零,则会导致调用线程让出。引入 zx_thread_legacy_yield 后,目标是移除对零截止日期的特殊处理。

此外,必须移除 syscalls_zx_nanosleep_zero_duration 内核计数器,同时引入 syscalls_zx_thread_legacy_yield 计数器。

实现

zx_nanosleep(0) 在 Fuchsia 树之外有 2 个调用点(提供 sched_yield 的实现),在树内有 7 个调用点。这涉及将工作拆分为四个 CL。

  1. 引入了新的系统调用 zx_thread_legacy_yield
  2. 将树内用户迁移到 zx_thread_legacy_yield
  3. 迁移非树型用户。
  4. zx_nanosleep 中移除了 yield 过载。

CL (1) 将包含文档、语言绑定更新,CL (4) 也将更新文档。(1) 和 (2) 可以合并到单个 CL 中,但将实现与迁移分开似乎更清晰。

性能

除了 zx_nanosleep 路径略有改进之外,对性能没有任何已知影响,因为移除了分支。

向后兼容性

zx_nanosleep(0) 的用户不限于根代码库。

安全注意事项

由于 zx_nanosleep(0)(现在)等同于 zx_thread_legacy_yield(0),因此现有代码和新代码的行为将完全相同。为防止出现任何安全问题,在 zx_nanosleep(0) 的所有用例都迁移到 zx_thread_legacy_yield(0) 之前,zx_nanosleep 将保持不变。

隐私注意事项

此提案对隐私权没有影响。

测试

由于 zx_thread_legacy_yield 的性质,因此很难进行可靠的测试,但至少我们可以验证返回代码是否符合预期。

文档

我们将为 zx_thread_legacy_yield 添加其他文档,并更新 zx_nanosleep 的条目,以移除提及零截止期限属于特殊情况的内容。

缺点、替代方案和未知情况

最大的缺点和顾虑是存在鼓励 zx_thread_legacy_yield 使用繁忙等待模式的情况,但 sched_yield 已经提供了此机制。通过适当的文档和最佳实践,可以缓解这些问题。由于此系统调用的目标用户是驱动程序,因此应仔细审核任何其他用法。

我们考虑的另一种替代方案是将魔法值更改为其他值(例如 INT_MIN)。这确实可以解决计算的截止期限问题,但仍会留下特殊情况。此替代方案还需要更新树外用户,因此与添加新的系统调用所需的工作量相同。最大的缺点是,这样做会使 zx_nanosleep 截止期限处理与处理截止期限的其他操作(例如 zx_object_wait)不同。

在先技术和参考文档

  • zx_nanosleep 使用 0 作为特殊值,表示“产量”。问题在于,有代码会有效地执行截止期限计算,并且可以计算出 0,在这种情况下,目的不是让出,而是相反:立即执行下一条语句。

  • 代码中包含 yield 通常表示某些操作执行有误。遗憾的是,在硬件缺少适当信号模式的驱动程序中,出现此问题并不罕见。