摘要
在线程上开始执行。
声明
#include <zircon/syscalls.h>
zx_status_t zx_thread_start_regs(zx_handle_t handle,
uint64_t pc,
uint64_t sp,
uint64_t arg1,
uint64_t arg2,
uint64_t tp,
uint64_t abi_reg);
zx_status_t zx_thread_start(zx_handle_t handle,
zx_vaddr_t pc,
zx_vaddr_t sp,
uintptr_t arg1,
uintptr_t arg2);
说明
_TODO(https://fxbug.dev/478347581): 具有 tp 和 abi_reg 实参的新签名是 Fuchsia API 级别 31 及更高版本中的首选 ABI。当不再支持 31 之前的 API 级别时,此属性最终将重命名为 zx_thread_start。旧签名具有完全相同的行为,新实参使用零。
zx_thread_start() 会使线程开始执行。其初始寄存器设置如下:
- 程序计数器设置为 pc 实参。
- 堆栈指针设置为 sp 参数。
- 机器的 C 调用约定中的前两个实参寄存器分别设置为 arg1 和 arg2。
- 机器的线程指针寄存器设置为 tp 实参。
- 机器 ABI 用于影子调用堆栈指针的寄存器设置为 abi_reg。在没有影子调用堆栈 ABI 的 x86 上,此值会进入
r15寄存器。 - 所有其他通用寄存器均为零。
- 所有浮点和/或向量寄存器都处于机器的初始状态(通常大部分为零)。
给定的每个寄存器值都必须是正常代码可能以某种方式进入该寄存器的值。否则,调用将失败并返回 ZX_ERR_INVALID_ARGS。例如,某些机器上的 PC 只能设置为“规范”地址:它不一定是有效地址,可以是会导致线程在该 PC 上实际执行时出现故障的地址,就像正常的跳转指令会设置 PC 然后出现故障一样;但它不能是“非规范”地址,在这种地址中,跳转指令本身会在不更改 PC 的情况下出现故障。同样,堆栈指针可能需要是具有有效机器所需对齐方式的指针(即使不是实际有效的地址);或者线程指针可能需要是规范地址。对于所有机器上的所有这些寄存器,零始终是有效的实参值。
当线程的最后一个句柄关闭时,该线程会被销毁。
线程句柄可以等待,并且当线程停止执行(由于调用了 zx_thread_exit())时,将断言信号 ZX_THREAD_TERMINATED。
pc 应指向一个函数,该函数必须在到达最后一条指令之前调用 zx_thread_exit() 或 zx_futex_wake_handle_close_thread_exit() 或 zx_vmar_unmap_handle_close_thread_exit()。示例如下:
[[noreturn]] void thread_entry(uint64_t arg1, uint64_t arg2) {
// do work here.
zx_thread_exit();
}
如果在到达函数末尾之前未能调用某个退出函数,则会导致特定于架构 / 工具链的异常。
权限
句柄必须是 ZX_OBJ_TYPE_THREAD 类型,并且具有 ZX_RIGHT_MANAGE_THREAD。
返回值
如果成功,zx_thread_start() 会返回 ZX_OK。如果失败,则返回负错误值。
错误
ZX_ERR_BAD_HANDLE thread 不是有效的句柄。
ZX_ERR_WRONG_TYPE thread 不是线程句柄。
ZX_ERR_ACCESS_DENIED 句柄 thread 缺少 ZX_RIGHT_WRITE。
ZX_ERR_BAD_STATE thread 尚未准备好运行,或者 thread 所属的进程不再处于活跃状态。
ZX_ERR_INVALID_ARGS 其中一个寄存器值无法供机器使用。