RFC-0237:使用 ZX_CLOCK_UPDATED 傳送時鐘更新信號 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 新增一種信號類型,在 Zircon 時鐘更新時傳送 |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2023-09-26 |
審查日期 (年-月-日) | 2024-01-03 |
摘要
這份 RFC 建議在 Zircon 時鐘中導入新的時鐘訊號 ZX_CLOCK_UPDATED
,每次時鐘更新時都會閃爍。
提振精神
時鐘是時鐘單調性參考時間軸的一維仿射變換,定義如何將「參考」時間 (即裝置的單調性時鐘) 轉換為時鐘輸出的「合成」時間。因此,UTC 時鐘是不斷調整的轉換函式,當套用至裝置單調時鐘的目前值時,會產生目前世界標準時間。
Zircon 中 UTC 時鐘的仿射變換,僅會由 Timekeeper 使用 syscall zx_clock_update
更新,且可供任何使用者使用 syscall zx_clock_get_details
讀取。
為了讓在 Starnix 上執行的 Linux 程式能夠使用 vDSO 函式 clock_gettime
或 gettimeofday
計算世界標準時間,Starnix vDSO 必須能夠存取從單調時間到世界標準時間的最新時鐘轉換。目前,Starnix 核心可以使用 zx_clock_get_details
定期對 Zircon UTC 時鐘進行時鐘轉換的輪詢,然後將此轉換載入 Starnix 核心和 Starnix 上執行的 Linux 程式的使用者空間共用記憶體中的網頁,以提供這項存取權。
閃爍是指對訊號進行無限快速的斷言和取消斷言。這表示等待時鐘訊號變更的觀察器可以偵測到閃爍,但不會有任何觀察器讀取要斷言的時鐘訊號值。透過引入 ZX_CLOCK_UPDATED
(在時鐘更新時會閃爍的時鐘訊號),Starnix 核心可以改為收到世界標準時間時鐘的更新通知,並從 Zircon 取得最新的轉換,然後在收到這些通知後立即更新 Linux 程式使用的時鐘轉換。這麼做可減少在 Linux 程式計算世界標準時間時,Zircon 中時鐘轉換變更與使用這項新轉換之間的潛在延遲時間。
相關人員
誰會受到這項 RFC 是否通過的影響?(此為選用部分,但建議您填寫)。
協助人員:
- cpu@google.com
審查者:
- abarth@google.com
- maniscalco@google.com
- johngro@google.com
諮詢:
- mariagl@google.com
- fdurso@google.com
- qsr@google.com
社會化:
與上述所有審查人員和顧問進行討論。這份文件之前有設計文件,並收到所有利益相關者提供的非正式意見回饋。
這份文件中的資訊已納入本 RFC,並在相關部分加以整合。
設計
Zircon 時鐘包含一個信號:ZX_CLOCK_STARTED
,會在時鐘啟動時提出。設計中新增了 ZX_CLOCK_UPDATED
時鐘信號,每次更新時鐘時,系統都會發送這項信號。
為了能夠閃爍信號,設計也涉及修改 Dispatcher::UpdateState
,目前用於更新 Zircon 信號。目前,該函式會採用兩個輸入內容:set_mask
和 clear_mask
,用於指定要設定 (斷言) 和清除 (取消斷言) 的信號。除了更新 set_mask
和 clear_mask
指定的信號,這個函式還會使用 NotifyObservers
函式,通知所有觀察器任何從非活動狀態轉為活動狀態的信號。
修改內容是將第三個輸入值新增至 UpdateState
,並命名為 strobe_mask
,預設值為零。這會指定要閃爍的所有信號。指定為閃爍的訊號不會變更值,但 NotifyObservers
呼叫會經過修改,以便通知所有觀察者 strobe_mask
指定的任何訊號,讓觀察者得知訊號已更新。
為了使用這個訊號,以便在不會讓使用者錯過更新的情況下,通知他們時鐘轉換的更新,使用者不應使用 zx_object_wait_one
或 zx_object_wait_many
等待信號閃爍。如果使用者讀取目前的時鐘詳細資料,然後呼叫 zx_object_wait_one
以等待時鐘更新,在讀取目前時鐘詳細資料和呼叫等待之間,Zircon 可能已更新時鐘,因此系統不會註冊這項更新。
請改用 zx_object_wait_async
。在讀取目前轉換作業之前,使用者應針對時鐘發布非同步等待作業。然後,在讀取時鐘詳細資料後,使用者就可以在發布非同步等待的端口上等待。這樣就能避免錯過時鐘詳細資料的更新。
這個機制的結果是,如果在建立非同步等待作業與讀取時鐘詳細資料之間更新時鐘,會導致在等待連接埠時立即喚醒,即使讀取的時鐘轉換為最新狀態也一樣。日後的作業可能會改進這項信號,以免發生這些誤喚醒的可能性。
實作
這項設計可在一個小型 CL 中實作。CL 會定義新的訊號,並修改 UpdateState 以納入新的 strobe_mask
輸入內容。
成效
Starnix 核心會使用這個新信號,減少在 Starnix 上執行的 Linux 程式世界標準時間時鐘的潛在錯誤。
目前,Starnix 是唯一建議使用這項信號的使用者,但日後可能會有其他使用者使用這項信號 (例如,為了支援 C++ 標準程式庫在 UTC 期限前封鎖執行緒的能力,而實作 C++ 執行階段)。使用 UpdateState
閃爍訊號的時間複雜度,與訊號觀察者的數量成線性關係。也就是說,當 ZX_CLOCK_UPDATED
的觀察員數量變多時,就會發生效能問題。
回溯相容性
任何現有信號的行為都不會改變,因此預期不會有向下相容性的問題。
安全性考量
這項提案不會造成任何安全性影響。
隱私權注意事項
這項提案不會對隱私權造成任何影響。
測試
我們會新增測試,驗證設計中指定的行為。這些測試會確保沒有任何使用者可以手動變更時鐘信號,且任何在時鐘 ZX_CLOCK_UPDATED
信號上等待閃光燈的觀察者,都會在時鐘更新時收到通知,且在沒有時鐘更新時不會收到信號觀察者的通知 (也就是說,在沒有時鐘更新時,系統不會斷言 ZX_CLOCK_UPDATED)。
說明文件
我們會更新下列說明文件,以說明 ZX_CLOCK_UPDATED
,以及使用者應遵循的方法時鐘,以免在使用此信號時錯過更新。
- /docs/concepts/kernel/time/utc/architecture.md
- /docs/concepts/kernel/time/utc/behavior.md
- /reference/kernel_objects/clock.md
- /reference/syscalls/clock_update.md
缺點和替代方案
缺點
本文件的「效能」一節說明瞭隨著信號觀察員數量增加,效能會降低的問題。如果時鐘訊號的觀察者數量增加到大量,可能需要進一步處理,以減輕這些效能問題。
替代方案
針對動機所提出的問題,另一個解決方案是將 Zircon UTC 時鐘的時鐘詳細資料直接對應至 Starnix 核心。接著,Starnix 核心就能將這段記憶體直接對應至 Linux 程序的空間。也就是說,Zircon 中的時鐘物件會立即更新至 Starnix 和 Linux 程序。這樣一來,就不需要引入新的訊號,而且不必降低傳播至 Starnix 的時鐘更新延遲時間,而是完全移除這項延遲時間。不過,這需要對 Zircon 核心進行大幅變更。