天天看點

OpenCore學習筆記(1)一、OPENCORE 之 Scheduler

一、OPENCORE 之 Scheduler

OsclScheduler

OsclExecScheduler

OsclExecSchedulerCommonBase

1. OsclScheduler::Init()

→ int AuthorDriver::authorThread()

→ OsclScheduler::Init("AndroidAuthorDriver");

→ OSCL_TRY(error, mAuthor = PVAuthorEngineFactory::CreateAuthor(this, this, this));

→ OSCL_EXPORT_REF void OsclScheduler::Init(const char *name, Oscl_DefAlloc *alloc, int nreserve)

→ OsclExecScheduler *sched = OsclExecScheduler::NewL(name, alloc, nreserve);

→ sched->InstallScheduler();

→ OsclExecScheduler * OsclExecScheduler::NewL(const char *name, Oscl_DefAlloc *alloc, int nreserve)

→ self = OSCL_PLACEMENT_NEW(ptr, OsclExecScheduler(alloc));

→ self->ConstructL(name, nreserve);

======

AddToScheduler();

PendForExec();

======

2. OsclExecSchedulerCommonBase::iReadyQ

→ status_t AuthorDriver::enqueueCommand(author_command *ac, media_completion_f comp, void *cookie)

    → mCommandQueue.push_front(ac);

    → PendComplete(OSCL_REQUEST_ERR_NONE);

→ OSCL_EXPORT_REF void OsclActiveObject::PendComplete(int32 aStatus)

→ void PVThreadContext::PendComplete(PVActiveBase *pvbase, int32 aReason, TPVThreadContext aCallingContext)

→ void OsclExecSchedulerCommonBase::PendComplete(PVActiveBase *pvbase, int32 aReason, TPVThreadContext aThreadContext)

    → iReadyQ.Add(pvbase, false); /// 将一個AO添加到iReadyQ中,并恢複BlockingLoopL

3. PVActiveBase::Run()

兩種情況,但似乎第二種沒用到

iBlockingMode=true

→ int AuthorDriver::authorThread()

→ OsclExecScheduler *sched = OsclExecScheduler::Current();

→ sched->StartScheduler(mSyncSem); // AuthorDriver的構造函數在建立完AuthorThread之後進入阻塞狀态,

→ OSCL_EXPORT_REF void OsclExecSchedulerCommonBase::StartScheduler(OsclSemaphore *aSignal)

→ BeginScheduling(true, false);//blocking, non-native

        if (aSignal)

            aSignal->Signal(); // 在beginScheduling執行完畢之後,AuthorDriver的構造函數就可以退出了

→ OSCL_TRY(err, BlockingLoopL(););  // 這裡不會立即傳回,要等整個程式停止

→ void OsclExecSchedulerCommonBase::BlockingLoopL() //

    → PVActiveBase* pvtimer = UpdateTimers(waitTicks);

    → PVActiveBase* pvactive = iReadyQ.PopTop();

    → CallRunExec(pvactive);    // OsclActiveObject

OR

    → iReadyQ.Wait(OsclTickCount::TicksToMsec(waitTicks))

    → iExecTimerQ.Pop(pvtimer);

    → CallRunExec(pvtimer);    // OsclTimerObject

OR

    → iReadyQ.Wait();    // Nothing is Ready, 在執行iReadyQ.Add時會調用iSem.Signal()

    → iReadyQ.Signal();

→ void OsclExecSchedulerCommonBase::CallRunExec(PVActiveBase *pvactive)

    → OSCL_TRY_NO_TLS(iErrorTrapImp, err, pvactive->Run(););

iBlockingMode=false

→ OSCL_EXPORT_REF void OsclExecScheduler::RunSchedulerNonBlocking(int32 aCount, int32 &aReady, uint32 &aShortestDelay)

→ BeginScheduling(false, false);//nonblocking, non-native

代碼太多,沒時寫很多東西,簡單的貼點代碼吧