摘要
为线程注册可重启序列。
声明
#include <zircon/syscalls.h>
zx_status_t zx_thread_set_rseq(zx_handle_t vmo, uint64_t offset, uint64_t size);
说明
zx_thread_set_rseq() 为当前线程注册可重启序列。可重启序列由 VMO 中的 zx_rseq_t 结构定义,从 offset 开始,长度为 size。
Zircon 会使 zx_rseq_t 结构中的 cpu_id 字段与线程的当前 CPU ID 保持同步。如果指令指针位于 start_ip 和 post_commit_offset 字段定义的可重启序列中时,线程迁移到其他 CPU,则线程将在 abort_ip 字段指定的地址处继续执行。
用户空间应使用易失性读写来访问 zx_rseq_t 结构,因为内核可能随时修改 cpu_id 字段,并且内核可能随时读取 start_ip、post_commit_offset 和 abort_ip 字段。
一次最多只能注册一个可重启序列。如果线程已注册可重启序列,zx_thread_set_rseq() 将返回 ZX_ERR_ALREADY_EXISTS。
offset 必须为 0 mod alignof(zx_rseq_t),并且从 offset 开始的大小为 sizeof(zx_rseq_t) 的区域不得跨越页面边界。
如需取消注册可重启序列,请使用 ZX_HANDLE_INVALID 作为 vmo 参数调用 zx_thread_set_rseq()。
返回值
zx_thread_set_rseq() 成功时会返回 ZX_OK。
如果失败,则返回负错误值。
错误
ZX_ERR_INVALID_ARGS offset 不是 alignof(zx_rseq_t) 的倍数,size 不是 sizeof(zx_rseq_t),或者由 offset 和 size 定义的内存区域跨越了页面边界。
ZX_ERR_INVALID_ARGS vmo 不可直接写入、已被标记为未缓存,或由用户分页器提供支持。
ZX_ERR_ALREADY_EXISTS 该线程已注册可重启序列。
ZX_ERR_BAD_HANDLE vmo 既不是有效的句柄,也不是 ZX_HANDLE_INVALID。
ZX_ERR_WRONG_TYPE vmo 不是 VMO。
ZX_ERR_ACCESS_DENIED vmo 缺少 ZX_RIGHT_READ、ZX_RIGHT_WRITE 或 ZX_RIGHT_DUPLICATE。