zx_pager_query_dirty_ranges

摘要

在分页器拥有的 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);

说明

查询 pager_vmo,以便在 [offset, offset + length) 是脏的,即具有尚未写回至分页器源的未完成修改。 pager_vmo 必须是之前由 zx_pager_create_vmo()pager 创建的。 offsetlength 不需要页面对齐,但在以下情况下,它们会四舍五入为页面边界 执行查询。

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 的脏范围的数量。

avail 是一个可选指针,用于返回可读取的脏范围数。如果 buffer 不够大,avail 将大于 actual

成功后,actual 将包含复制到 buffer 的脏范围的数量。 复制到 buffer 的脏范围的数量受 buffer_size 的限制,即 [offset, offset + length] 可能存在更多 存储在缓冲区中。调用方可以假定在之前已变成脏的范围。 进行调用时,其要么包含在缓冲区中,要么具有严格大于该值的开始偏移量 高于缓冲区中的最后一个范围的值。因此,调用方可以推进 offset 并再次进行查询 来发现更多脏范围,直到 avail 为零。

想要查询 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 pagerpager_vmo 不是有效的句柄。

ZX_ERR_WRONG_TYPE pager 不是分页器句柄,或 pager_vmo 不是 VMO 句柄。

ZX_ERR_ACCESS_DENIED 分页器不含 ZX_RIGHT_MANAGE_VMOpager_vmo 不含 ZX_RIGHT_READ

ZX_ERR_INVALID_ARGS pager_vmo 不是通过 pager 创建的 VMO,或者 buffer 无效 指针。

ZX_ERR_OUT_OF_RANGEpager_vmo 中指定的范围无效。

另请参阅