Zircon 系統介面評分量表

Zircon 系統介面會以 libzircon.so vDSO API 介面表示。

介面中的函式名稱必須以 zx_ 開頭,預處理器巨集名稱則必須以 ZX_ 開頭。定義為介面一部分的類型,名稱開頭必須是 zx_,結尾必須是 _t。

介面中的每個函式都必須在 /docs/zircon/syscalls/ 中以 Markdown 檔案記錄,並從 /docs/zircon/syscalls.md 連結。

函式名稱

函式名稱必須完全由小寫英文字母和底線組成,且符合下列語法:

zx_<noun>_<verb>{_<direct-object>}

例如:

zx_handle_close, zx_channel_write, zx_object_signal_peer

名詞通常是核心物件類型,但也可以是其他名詞,例如沒有對應核心物件的 clock 或 ticks。其他函式則使用較抽象的名詞,例如 system 或 status。

名詞和動詞不得包含底線 (以免混淆文法)。名詞和動詞應各為單一英文字,但如果沒有合適的字詞或字詞過長,則可使用首字母縮略字 (或縮寫)。

直接受詞可包含底線。

部分函式會執行複合運算。在這種情況下,函式名稱可能是由元件作業的名稱串連而成。

部分函式會對多種核心物件執行作業,在這種情況下,名詞是較抽象的物件類型。例如,含有名詞 object 的函式會對大多數核心物件執行作業,而含有名詞 task 的函式則會對工作、程序和執行緒執行作業。

類型

使用 zx_status_t 代表成功和失敗。

使用固定大小的整數類型。函式不得使用 short、int 或 unsigned long (或類似類型)。請改用 int16_t、int32_t 和 uint64_t 等類型。

緩衝區長度、元素大小和元素數量請使用 size_t。

使用 void* 指向呼叫端位址空間中的任意類型。如果位址可能位於其他位址空間,請使用 zx_vaddr_t / zx_paddr_t。

使用 zx_time_t 設定逾時,必須以系統單調時鐘時基中的絕對期限 (以奈秒為單位) 表示。在絕對期限不合理的情況下 (例如計時器鬆弛),請使用 zx_duration_t 表示沒有特定時間基準的時間量 (以奈秒為單位)。

參數

接收器

絕大多數函式都會對控制代碼執行操作,控制代碼是指向核心物件的參照,其類型與函式名稱中的名詞相符。這個控制代碼是這類函式的第一個引數,稱為接收器。

將接收器命名為 handle。

物件建立函式 (例如 zx_channel_create、zx_event_create) 可能不會採用控制代碼引數。這些函式會隱含地對目前程序執行。

選項參數

函式通常包含 options 參數,可允許影響作業的旗標,並留有空間,以便在日後修訂 API 時新增更多旗標。

options 參數請使用 uint32_t 類型和 options 名稱。

如果存在,options 參數必須是接收器控制代碼後的第一個引數,如果函式沒有接收器,則必須是整體的第一個引數。

並非所有函式都需要 options 參數。

個別選項值必須定義為預處理器巨集,將數字常值轉換為 uint32_t。選項必須是位元旗標,可使用位元 | 運算子組合。

版本管理結構體

跨越 syscall 邊界的結構體是 ABI 的一部分,無法就地變更。接受或傳回 struct 的函式必須包含參數,讓呼叫端指定 struct 的版本,例如 topic 參數或 options 參數中保留的版本位元。請勿在 struct 本身新增版本欄位。

如要變更現有結構體,請按照「建立系統呼叫結構體版本」一節所述,新增結構體版本。

帳號代碼

如果函式接收控制代碼做為參數,則必須一律使用控制代碼,或一律不使用,但有以下例外狀況:

  • 如果函式採用 options 參數,則可能會有非預設選項,避免在各種錯誤情況下耗用控制代碼。

  • 如果函式不接受 options 參數,則在傳回 ZX_ERR_SHOULD_WAIT 時,函式可能會避免耗用控制代碼。

緩衝區 (含資料、數量/大小和/或實際值)

請一律為陣列或緩衝區提供計數或大小 (類型為 size_t),包括字串。如果緩衝區是由函式寫入,則函式必須具有傳回寫入資料計數或大小的 out 參數。

如果是讀取和寫入樣式作業,緩衝區的指標後面會接著緩衝區計數或大小,如果可以進行短讀取或寫入,則輸出參數會在成功時提供實際計數或大小:

zx_status_t zx_socket_write(zx_handle_t handle, uint32_t options,
                            const void* buffer, size_t size, size_t* actual);

如果有多個緩衝區,緩衝區、長度和輸出參數會以一致的順序交錯顯示。例如,請參閱 zx_channel_read:

zx_status_t zx_channel_read(zx_handle_t handle, uint32_t options,
                            void* bytes, zx_handle_t* handles,
                            uint32_t num_bytes, uint32_t num_handles,
                            uint32_t* actual_bytes, uint32_t* actual_handles);

輸出

out 參數是函式寫入的純量值。舉例來說,如果函式會寫入 uint32_t 來傳回 CPU 數量,則該函式具有輸出參數。如果函式填入用戶端提供的緩衝區,則緩衝區不是輸出參數。

輸出參數一律位於參數清單結尾。

輸出參數不得同時為輸入參數。舉例來說,如果函式具有 out 參數,可透過該參數傳回寫入緩衝區的位元組數,則函式不得同時使用該參數,從呼叫端接收緩衝區長度。

傳回類型

絕大多數函式的傳回類型都是 zx_status_t,成功時為 ZX_OK,失敗時為 ZX_ERR_...。

請勿透過 zx_status_t 傳回其他值,例如使用正值範圍。請改用 out 參數。

其他傳回類型可用於不會失敗的函式。例如,zx_thread_exit 一定會退出執行緒,且傳回類型為 void。同樣地,zx_clock_get_monotonic 必定能取得目前時間,且傳回類型為 zx_time_t。

函式專屬規則

zx_object_get_property 與 zx_object_get_info

有兩種相似的機制可用於公開物件相關資料:zx_object_get_property 和 zx_object_get_info。如果 (a) 屬性可以使用 zx_object_set_property 設定,或 (b) 屬性存在於多種物件類型中,建議透過 zx_object_get_property 公開資料。在其他情況下,請考慮將資料納入具有該屬性的物件類型的一般 zx_object_get_info 主題中。