总结
在分页器拥有的 VMO 中查询连续范围的脏页。
声明
#include <zircon/syscalls.h>
zx_status_t zx_pager_query_dirty_ranges(zx_handle_t pager,
zx_handle_t pager_vmo,
uint64_t offset,
uint64_t length,
void* buffer,
size_t buffer_size,
size_t* actual,
size_t* avail);
说明
针对 [offset, offset + length) 范围内的连续页面查询 pager_vmo,这些页面是脏页,即具有尚未写回分页器来源的待处理修改。pager_vmo 必须是 zx_pager_create_vmo()
之前通过分页器创建的。
offset 和 length 无需页面对齐,但它们在执行查询时会被四舍五入为页面边界。
buffer 应指向一个 zx_vmo_dirty_range_t
结构体数组,用于保存查询结果,buffer_size 应可容纳该数组。
typedef struct zx_vmo_dirty_range {
// Represents the range [offset, offset + length).
uint64_t offset;
uint64_t length;
// Any options applicable to the range.
// ZX_VMO_DIRTY_RANGE_IS_ZERO indicates that the range contains all zeros.
uint64_t options;
} zx_vmo_dirty_range_t;
actual 是一个可选指针,用于返回已写入 buffer 的脏范围数。
availability 是一个可选指针,用于返回可供读取的脏范围数量。如果 buffer 不够大,则 availability 将大于 actual。
如果成功,“actual”将包含已复制到“缓冲区”的脏范围数量。 调用方可以假定,在进行调用之前被设为脏范围的任何范围要么包含在 buffer 中,要么其起始偏移量严格大于 buffer 中的最后一个范围。因此,调用方可以推进 offset 并执行另一个查询来发现更多脏范围,直到 availability 为零。
想要查询 VMO 中的所有脏范围的用户代码示例可能如下所示:
zx_vmo_dirty_range_t ranges[5];
size_t actual = 0;
size_t avail = 0;
uint64_t start = 0;
uint64_t len = vmo_size;
while (len > 0) {
zx_status_t st = zx_pager_query_dirty_ranges(pager, vmo, start, len,
&ranges[0],
5 * sizeof(zx_vmo_dirty_range_t),
&actual, &avail);
// Process the |ranges| returned as needed.
ProcessDirtyRanges(&ranges[0], actual);
// We've read all the dirty ranges that existed before the query.
if (actual == avail) {
break;
}
// We used up the entire |ranges| buffer, but there are more dirty ranges to be read.
// Advance start beyond the last dirty range found.
uint64_t new_start = ranges[4].offset + ranges[4].length;
len -= (new_start - start);
start = new_start;
}
权限
pager 必须为 ZX_OBJ_TYPE_PAGER
类型且具有 ZX_RIGHT_MANAGE_VMO
。
pager_vmo 的类型必须为 ZX_OBJ_TYPE_VMO
且设为 ZX_RIGHT_READ
。
返回值
zx_pager_query_dirty_ranges()
会在成功时返回 ZX_OK
。如果失败,则返回负的错误值。
错误
ZX_ERR_BAD_HANDLE
pager 或 pager_vmo 不是有效的句柄。
ZX_ERR_WRONG_TYPE
pager 不是分页器句柄,或 pager_vmo 不是 VMO 句柄。
ZX_ERR_ACCESS_DENIED
pager 没有 ZX_RIGHT_MANAGE_VMO
或 pager_vmo 没有 ZX_RIGHT_READ
。
ZX_ERR_INVALID_ARGS
pager_vmo 不是通过 pager 创建的 VMO,或者 buffer 是无效的指针。
ZX_ERR_OUT_OF_RANGE
pager_vmo 中指定的范围无效。
另请参阅
zx_pager_create_vmo()
zx_pager_detach_vmo()
zx_pager_op_range()
zx_pager_query_vmo_stats()
zx_pager_supply_pages()