本頁討論內嵌和非內嵌呼叫的效能層面 由駕駛調度員製作。
瞭解 內嵌和非內嵌呼叫可協助您 最佳化 Fuchsia 的驅動程式庫反應能力和整體系統效能。 本頁會說明哪些條件 就無法透過內嵌方式進行,並影響其效能。 此外,系統也會 用於調查的偵錯技術 非內嵌呼叫。
內嵌和非內嵌呼叫
當調度員需要「致電驅動程式庫」時 ( 是代表驅動程式庫在執行緒上執行工作,調度工具會先 會決定通話是否能夠內嵌。如果不要內嵌 安排在稍後的時間點進行。
這些呼叫的主要差異如下:
- 內嵌:調度員立即撥打電話給驅動程式庫。提出要求者 接收方才接收到傳送者,而不返回執行階段迴圈 (見圖 1)。
- 非內嵌:調度員安排在日後通話 執行階段迴圈的疊代作業 (見圖 2)。
內嵌呼叫比非內嵌呼叫更有效率。舉例來說 內嵌單向管道呼叫大約需要 2 毫秒,非內嵌式訊息 單向管道呼叫最多可能需要 10 毫秒。
圖 1. 內嵌呼叫的流程。
圖 2. 非內嵌呼叫的流程。
非內嵌呼叫的條件
如果發生下列任一情況,調度器不會進行內嵌呼叫 適用條件:
調度工具允許封鎖來電,但傳送者不允許。
如果目標調度工具有 已設定
ALLOW_SYNC_CALLS
選項,但寄件者是寄件者 調度器不會。以免妨礙 在同一呼叫堆疊中使用調度工具。調度工具已同步且非處於閒置狀態。
這個條件僅適用於 同步處理調度工具。通話時 驅動程式庫執行階段,驅動程式庫執行階段會檢查調度工具是否處於閒置狀態。 如果處於閒置狀態,系統就不會撥打電話,以免觸發 平行呼叫傳入驅動程式庫。
呼叫來自不受驅動程式庫執行階段管理的執行緒。
驅動程式庫產生時,不會由驅動程式庫程式執行階段管理執行緒 自己的執行緒 (例如
std::thread
或thread_create
) 方法。與 FIDL 接收端相關聯的管道尚未準備就緒。
FIDL 傳輸元件會使用管道 (Zircon) 透過管道收發訊息 或驅動程式庫交通管道如要接收訊息,請稍待片刻 必須由 FIDL 層在管道上註冊 (程序由 FIDL 層處理) FIDL 繫結在背景中執行)。如果時間沒有登記等待時間 卻無法以內嵌方式發出呼叫。
這通來電視為重新參加通話。
在圖 3 中,駕駛人 A 傳送 FIDL 要求給驅動程式 B 時,並收到該要求 內嵌,不過駕駛 B 會立即回覆駕駛 A,但這則訊息 屬於駕駛 A 的 reentrant。在這種情況下,調度器 ,代表駕駛 A 做出非內嵌呼叫,從駕駛人 B 傳送回覆。
無論調度員服務哪位調度員,重複檢查皆適用於所有調度員。 例如,如果驅動程式庫有兩名調度員,傳送和接收訊息 這兩名調度員之間一律視為重新申請,無法 內嵌式。
呼叫是使用 Zircon 管道傳輸的 FIDL 要求。
只有驅動程式傳輸支援 FIDL 內嵌功能。 與 Zircon 管道不同,驅動程式庫傳輸管道僅適用於程序 可在驅動程式庫傳輸中使用特殊的內嵌實作 管道邏輯
圖 3. 因重複傳送而非內嵌呼叫的流程。
對非內嵌呼叫進行偵錯
fdf_env_dispatcher_dump
函式可協助駕駛人偵錯
呼叫不會以內嵌方式發出這個函式會記錄
非內嵌呼叫,例如:
INFO: [my_driver.cc(212)] ---- Runtime Dispatcher Dump Begin ----
INFO: [my_driver.cc(212)] The current thread is not managed by the driver runtime.
INFO: [my_driver.cc(212)] Dispatcher to dump: TestBody (0x24a7614d4240) (driver 0x10)
INFO: [my_driver.cc(212)] Synchronized: true
INFO: [my_driver.cc(212)] Allow sync calls: false
INFO: [my_driver.cc(212)] State: running
INFO: [my_driver.cc(212)] Processed 5 requests, 3 were inlined
INFO: [my_driver.cc(212)] Reasons why requests were not inlined:
INFO: [my_driver.cc(212)] * The request would have been reentrant: 2 times
INFO: [my_driver.cc(212)] * Another thread was already dispatching a request: 1 times
INFO: [my_driver.cc(212)] No queued tasks