| RFC-0142:zx_thread_legacy_yield | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 導入用於產生值的專用系統呼叫。 |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-11-29 |
| 審查日期 (年-月-日) | 2021-10-13 |
摘要
我們建議新增系統呼叫 zx_thread_legacy_yield,讓呼叫執行緒將 CPU 讓給其他等待中的執行緒。此外,如果截止日期等於零,我們會移除 zx_nanosleep 的特殊情況。系統呼叫名稱中的 legacy 表示有更合適的機制可用來達成所需行為。
提振精神
zx_nanosleep 的行為與所有其他系統呼叫處理期限的方式不同,也就是說,如果期限早於目前時間,系統會立即傳回。目前這是特殊情況,截止日期值為零表示收益。
此外,在執行階段無法判斷截止日期是否刻意設為零,或是計算結果。這會簡化 zx_nanosleep 的運作方式,減少開發人員需要注意的特殊情況。您可以手動將期限設為零,讓執行緒產生結果,也可以將期限設為零,做為下一個喚醒作業的結果 (表示立即繼續)。
利害關係人
誰會受到這項 RFC 是否通過的影響?(這個部分為選填,但建議填寫)。
協助人員:
由 FEC 指派,負責在 RFC 程序中引導此 RFC 的人員。
審查者:
已諮詢:
社交化:設計最初是在設計文件中討論。
設計
這項提案包含對 Zircon 系統呼叫 API 的下列變更:
- 新增
zx_thread_legacy_yield - 簡化
zx_nanosleep
其中 zx_thread_legacy_yield 定義如下:
/// Yields cpu to another waiting thread.
/// `options`: Reserved for future extension. Must be zero.
/// @blocking
zx_status_t zx_thread_legacy_yield(uint32_t options);
在使用者空間應用程式上呼叫 zx_thread_legacy_yield 時,呼叫執行緒會產生 CPU。options 參數可用於稍後導入提示。
呼叫 zx_thread_legacy_yield 時,如果 options 等於零,保證會傳回 ZX_OK。
如果呼叫 zx_nanosleep 時的期限大於單調時鐘的時間,呼叫執行緒就會進入休眠狀態,直到達到期限 (加上鬆弛時間) 為止。另一方面,如果期限的值等於或早於單調時鐘的時間,則會立即傳回。但如果截止時間為零,則會導致呼叫執行緒產生。導入 zx_thread_legacy_yield 後,目標是移除零期限的特殊處理方式。
此外,必須移除 syscalls_zx_nanosleep_zero_duration 核心計數器,並導入 syscalls_zx_thread_legacy_yield 計數器。
實作
zx_nanosleep(0) 在紫紅色樹狀結構外有 2 個呼叫點(提供 sched_yield 的實作項目),樹狀結構內則有 7 個呼叫點。這項作業需要將工作分成四個 CL。
- 導入新的系統呼叫
zx_thread_legacy_yield。 - 將樹狀結構內的使用者遷移至
zx_thread_legacy_yield。 - 從樹狀結構中遷出使用者。
- 從
zx_nanosleep移除收益過載。
CL (1) 將包含說明文件和語言繫結更新,CL (4) 也會更新說明文件。(1) 和 (2) 可以合併為單一 CL,但將實作與遷移作業分開,似乎是較乾淨的路徑。
效能
除了 zx_nanosleep 路徑略有改善 (因為移除了分支) 之外,效能不會受到任何已知影響。
回溯相容性
zx_nanosleep(0)的使用者不限於詞幹存放區。
安全性考量
現有程式碼和新程式碼的行為完全相同,
因為 zx_nanosleep(0) (現在) 等於 zx_thread_legacy_yield(0)。
為避免發生任何安全性問題,在所有 zx_nanosleep(0) 用途都遷移至 zx_thread_legacy_yield(0) 之前,zx_nanosleep 將維持不變。
隱私權注意事項
這項提案不會影響隱私權。
測試
zx_thread_legacy_yield 的性質使得可靠測試變得困難,但至少我們可以驗證回傳代碼是否符合預期。
說明文件
我們會為 zx_thread_legacy_yield 新增其他說明文件,並更新 zx_nanosleep 的項目,移除零期限為特例的說明。
缺點、替代方案和未知事項
最大的缺點和疑慮是存在zx_thread_legacy_yield鼓勵忙碌等待模式的機制,但 sched_yield 已提供這項機制。透過適當的文件和最佳做法,即可減輕這些疑慮。由於這個系統呼叫的目標使用者是驅動程式,因此應仔細檢查任何其他用途。
我們也考慮過將魔法值變更為其他值 (例如 INT_MIN )。這確實能解決計算截止日的問題,但仍會留下特殊情況。這個替代方案也需要更新樹狀結構外的使用者,因此與新增系統呼叫需要相同的工作量。最大的缺點是,這樣做會導致 zx_nanosleep 截止期限處理作業與處理截止期限的其他作業 (例如 zx_object_wait ) 不同。
既有技術和參考資料
zx_nanosleep使用 0 做為特殊值,表示「產生」。問題在於有程式碼會有效計算截止時間,但可能會計算出 0,在這種情況下,意圖並非產生結果,而是要「立即」執行下一個陳述式。代碼
yield通常表示有錯誤發生。 很遺憾,如果驅動程式的硬體缺少適當的信號模式,就經常會發生這種情況。