zx_pager_query_dirty_ranges

摘要

在 Pager 擁有的 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 將大於實際大小。

成功時,「實際」會包含複製到「buffer」的骯髒範圍數量。 複製到「buffer」的骯髒範圍數量受限於 buffer_size,也就是說,[offsetoffset + length] 有可能在「buffer」中,存在更多骯髒範圍。呼叫端可以假設在呼叫前發生任何骯髒範圍,就會包含在「緩衝區」中,或者啟動偏移量大於「緩衝區」中的最後一個範圍。因此,呼叫端可以推進 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 pager 沒有 ZX_RIGHT_MANAGE_VMOpager_vmo 沒有 ZX_RIGHT_READ

ZX_ERR_INVALID_ARGS pager_vmo 並非透過「pager」建立的 VMO,或「buffer」是無效的指標。

ZX_ERR_OUT_OF_RANGE pager_vmo 中的指定範圍無效。

另請參閱