2010年7月21日 星期三

淺談 OpenCore execution model

由於新工作與 OpenCore 有關, 前輩考量到未來對效能調整, 希望我能了解 OpenCore 架構
為此而稍微細看OpenCore, 感到非常"新奇", "有趣"

在此先不細談 OpenCore 整體 Object Model, 而這部份網路上的談論也不少
大致上即是分為 Engine - PVMF Node - Component 三層

這裡談 OpenCore 中的執行運作模式
或許是OpenCore 受到 Symbian Active Object Framework 諸多影響(文件上也有諸多Symbian字眼)
基本上, 對於Symbian 個人認知不深
然而對於OpenCore這樣注重 realtime 特性的 Multimedia Framework 採用這樣的方式感到"新奇"


上圖為運作的圖解
OpenCore 內基本執行單位為 PVActiveBase
而衍生出的 class 為 OsclActiveObject(AO) 與 OsclTimerObject(TO)
實作中需要被執行的元件繼承 AO or TO
而每個繼承AO/TO的類別需要個別實作其要不斷被執行的 Run() 介面

OpenCore 執行模式為 single thread
在 OsclScheduler::BlockLoopL() 這個無線迴圈當中
透過 WaitForActiveObject() 來取得下一個需要被執行的AO/TO
接著呼叫 CallRunExec() 來執行 AO/TO 的 Run()

對於規劃中需要被執行的AO/TO物件
只要沒腦地執行 PVActiveBase::AddToScheduler() 即可
接著便會依序被執行該AO/TO所實作的 Run()

看似簡單的行為, 然而直覺操作上卻讓人毫無頭緒
是的, 介面上無需透過具體的 scheduler instance, 從何來, 哪裡去就像黑盒子般
這點一時間讓我有點難以接受
細看實作上透過 macro 的方式取得 current thread 的 scheduler
只能說如此的 execution model 機制顯得不太clean
這樣的 model 基本上如果是為了 single thread/co-operative multitasking 的考量
也算說得過去, 只能說真的不是很優雅與直覺

再來, 其中最有趣的一點便在於 OsclTimer 與 PVMFMediaClock 這兩個 timer 類別
實作中AO/TO通常向此兩者註冊callback function 希望通知特定 time event 的發生
OsclTimer (oscl/oscl/osclproc/src/oscl_timer.h) 仰賴著 CallbackTimer
CallbackTimer 繼承自 "OsclTimerObject" ~ Wow~
看看 PVMFMediaClock (pvmi/pvmf/include/pvmf_media_clock.h)
一堆繼承物件中, 第一個物件即為 "OsclTimerObject"
而兩者的 Constructor 都呼叫了 AddToScheduler()
其時間的資訊是去 polling 系統的 OsclTickCount 得知

這麼看來 Timer 這點可"有趣"了, Timer 的運作與通知機制也仰賴著這個 BlockLoopL
而如果某一 AO/TO Run() 稍微久一點, Timer Event 可能就失真不少

ex:
試想, 假若一個 decoder 具有硬體加速, 然而 interrupt 有問題
因此採用 polling 方式以得知硬體狀態
component 中期望 timer 能夠每 10 ms 通知一次,
方便於 check 硬體狀態來決定是否要命令硬體 decode 下一張 frame
而在此同時 audio decoder 為軟體實作, 每解一個單位需要 30ms
這麼一來 ......

是的, 如果要遷就這樣的 model, 每個 component 實作上必須特別考量到 timing
而軟體實作上可能必須是 progressive 的方式, 不要一次將全部結果解出, 減少 Run() 單一執行時間長度
以這樣的方式, 來換得 timing 的精確度

如果是為了遷就不用 thread 而使用這樣的 timer 實作呢?
那 Audio 處理與 proxy interface 中就不該大剌剌地使用 OsclThread

anyway, 很高興在 trace 期間自 jserv 那聽到 2.2 已是預設的 StageFright
雖然目前實作不若 OpenCore 完整, 然而看來就個人的理解是"正常"多了 ...

20100727 後記: 應該好好說明一下 proxy interface, 其實本文中舉的例子並不一定會出現, 這裡用這樣的例子來解釋這樣的方式的問題, 文中例子的發生與否取決於是否使用proxy interface(是的, 這是compile option, 而且意義並非網路proxy), 在OpenCORE 中 codec 以 openmax 封裝為 omx_xxx_component, 若透過 proxy interface 即 create 了各 codec 的 thread. 儘管 OpenCORE 中透過使用proxy interface如此與設計不同的方式來避開 codec 的時間問題, timer 依舊容易受到 system I/O 與 parser 之類的影響.

沒有留言:

在 ARM 平台上使用 Function Multi-Versioning (FMV) - 以使用 Android NDK 為例

Function Multi-Versioning (FMV) 過往的 CPU 發展歷程中, x86 平台由於因應各種應用需求的提出, 而陸陸續續加入了不同的指令集, 此外也可能因為針對市場做等級區隔, 支援的數量與種類也不等. 在 Linux 平台上這些 CPU 資訊可以透過...