防止資料處理管道遭到暫停
在許多情況下,事件需要多個元件參與處理。假設您是驅動程式庫,收到可能會喚醒系統的事件,或是在系統喚醒時收到事件,應防止系統暫停。中斷處理驅動程式庫通常可能不知道事件的重要性,並將事件傳遞給其他驅動程式庫或元件。
您可以選擇幾種方式管理這項交接作業。為方便討論,假設 Driver X 收到中斷訊號,並透過 FIDL 訊息將事件交給 Driver Y。如果 X 是驅動程式庫,而 Y 是非驅動程式庫元件,則這兩個選項同樣適用。
接力棒傳遞
解決這個問題的方法之一,是連帶事件資料傳遞接力棒。 「接力」是指接力賽的概念,參與者會將物體從一人傳遞給另一人,以完成任務 (即賽跑)。
我們的接力棒可以是 LeaseToken (我們之前討論過),也可以是 fuchsia.power.broker/LeaseControl 管道。我們會使用 LeaseToken,因為我們已經討論過這些項目,而且與 LeaseControl 相比,這些項目更容易使用。
當 X 收到中斷時,會執行下列操作:
- 通話
ActivityGovernor.AcquireWakeLease - 確認中斷
- 對事件進行任何處理,例如轉換為新類型
- 將事件和從
AcquireWakeLease取得的LeaseToken傳遞至 Y
這個方法需要變更 X 和 Y 之間使用的通訊協定。使用下述的通訊協定互鎖機制則不需要,但有其他缺點。
如果系統的事件發生率很高,可能會發現每次事件都呼叫 ActivityGovernor.AcquireWakeLease 的 IPC 負擔過高。在這些情況下,Driver X 可以複製 LeaseToken (因為這實際上只是 Zircon 事件配對的控制代碼),並傳遞副本,同時保留原始副本一段逾時時間,而不是單純將 LeaseToken 從 X 移至 Y。如果選擇使用逾時,請謹慎選擇逾時時間,因為系統必須等到所有 LeaseToken 副本都已捨棄,才能暫停。強烈建議不要使用過長的逾時時間,使用逾時時間的原因是事件率相對較高,這表示您應該可以選擇較短的逾時時間。如果您編寫的是 C++,可以使用 TimeoutWakeLease 類別管理租約,並根據新事件的抵達時間延長逾時時間。呼叫 AcquireWakeLease 即可使用輔助程式,不必自行與 ActivityGovernor 能力互動。
通訊協定互鎖
如果 Driver X 和 Driver Y 的事件傳遞通訊協定包含確認,或已新增這項確認,「通訊協定互鎖」就是其中一個選項。通訊協定互鎖是由 Y 在確認收到事件前,先呼叫 ActivityGovernor.AcquireWakeLease 實作。
這個方法的步驟如下:
- X 通電話
ActivityGovernor.AcquireWakeLease - 確認中斷
- X 會對事件執行必要處理作業,可能將事件轉換為新類型
- 將事件傳遞至 Y
- Y 撥打
ActivityGovernor.AcquireWakeLease - Y 向 X 確認已收到事件
- X 推出
LeaseToken - Y 對事件執行任何處理作業
- Y 掉落
LeaseToken
如果通訊協定已有確認,則通訊協定互鎖「不需要」變更 X 和 Y 之間使用的通訊協定。這項策略會增加對系統活動管理員的 IPC 呼叫次數。通話次數增加是否有意義,取決於事件的速率,以及 X 和 Y 是否在逾時期間保留 LeaseToken。如果選擇使用逾時,請謹慎選擇逾時時間,因為系統必須等到 LeaseToken 捨棄後,才能暫停。強烈建議不要使用過長的逾時時間,使用逾時時間的原因是事件率相對較高,這表示您應該可以選擇較短的逾時時間。如果您使用 C++ 撰寫程式碼,可以透過 TimeoutWakeLease 類別管理租約,並根據新事件的抵達時間延長逾時時間。呼叫 AcquireWakeLease,使用輔助程式,而不是自行與 ActivityGovernor 能力互動。
逾時
使用逾時來確保系統正確性,並非整合電源架構的首選方式。其他選項只會將逾時做為最佳化方式。由於很難找出合適的逾時值,逾時可能會導致無法預測的行為。此外,通常必須針對每個用途、產品設定和硬體設定組合調整逾時,因此管理逾時是一項重要工作。逾時本質上是競爭條件,因此對於任何指定的逾時值,它可能允許您在大多數時間贏得競爭,直到突然無法為止。通常只有在軟體部署到大型測試或使用者群組後,才會發現失敗,而觀察到失敗時,往往會造成混淆。
有時逾時是唯一可行的選項。如果發生逾時,我們將讓 Driver X 呼叫 ActivityGovernor.AcquireWakeLease、確認中斷,然後保留租約,直到逾時為止,Driver Y 永遠不會看到租約。如果在逾時前收到另一個中斷訊號,驅動程式 X 只要延長逾時時間,不必取得額外租約。如果您要編寫 C++,可以使用輔助類別管理租約,並根據新中斷的抵達時間延長逾時。呼叫 AcquireWakeLease 即可使用輔助程式,不必自行與 ActivityGovernor 能力互動。