1.初始化和注册
camx/src/core/chi/camxchisession.cpp
CamxResult CHISession::Initialize(
CHISessionCreateData* pCreateData)
{
CamxResult result = CamxResultSuccess;
CHAR wrapperName[FILENAME_MAX];
CAMX_ASSERT(NULL != pCreateData);
CAMX_ASSERT(NULL != pCreateData->sessionCreateData.pThreadManager);
CAMX_ASSERT(NULL != pCreateData->sessionCreateData.pChiContext);
result = Session::Initialize(&pCreateData->sessionCreateData);
if (CamxResultSuccess == result)
{
m_localInstance = CamxAtomicIncU(&s_numInstances);
OsUtils::SNPrintF(&wrapperName[0], sizeof(wrapperName), "CHISessionWrapper%p", this);
result = m_pThreadManager->RegisterJobFamily(ThreadJobCallback,
wrapperName,
NULL,
JobPriority::Normal,
TRUE,
&m_hJobFamilyHandle);
result = m_pThreadManager->RegisterJobFamily(ThreadJobCallbackRequest,
wrapperName,
NULL,
JobPriority::Normal,
TRUE,
&m_hJobFamilyHandleRequest);
}
return result;
}
camx-common/utils/src/camxthreadmanager.cpp
CamxResult ThreadManager::RegisterJobFamily(
JobFunc jobFuncAddr,
const CHAR* pJobFuncName,
JobCb flushDoneCb,
JobPriority priority,
BOOL isSerialize,
JobHandle* phJob)
{
CamxResult result = CamxResultSuccess;
result = m_pJobRegistry->RegisterNewJob(jobFuncAddr, pJobFuncName, flushDoneCb,
priority, isSerialize, phJob);
return result;
}
camx-common/utils/src/camxthreadjobregistry.cpp
CamxResult JobRegistry::RegisterNewJob(
JobFunc jobFuncAddr,
const CHAR* pJobFuncName,
JobCb flushDoneCb,
JobPriority priority,
BOOL isSerialize,
JobHandle* phJob)
{
CamxResult result = CamxResultSuccess;
UINT32 slot = 0;
UINT32 counter = 0;
RegisteredJob* pRegisteredJob = NULL;
m_pRegistryLock->Lock();
BOOL jobAlreadyRegistered = IsJobAlreadyRegistered(phJob);
BOOL freeSlotsAvailable = IsFreeSlotAvailable(&slot, &counter);
if ((TRUE == jobAlreadyRegistered) ||
(FALSE == freeSlotsAvailable))
{
CAMX_LOG_ERROR(CamxLogGroupUtils,
"No more jobs can be registered, jobAlreadyRegistered: %d and has freeSlotsAvail: %d",
jobAlreadyRegistered,
freeSlotsAvailable);
result = CamxResultEFailed;
}
// A job registered will live on in the registry till the lifetime of the camera session
if (CamxResultSuccess == result)
{
pRegisteredJob = &m_registeredJobs[slot];
Utils::Memset(pRegisteredJob, 0x0, sizeof(RegisteredJob));
pRegisteredJob->funcAddr = jobFuncAddr;
pRegisteredJob->flushDoneCb = flushDoneCb;
pRegisteredJob->priority = priority;
pRegisteredJob->isSerial = isSerialize;
pRegisteredJob->slot = slot;
pRegisteredJob->uniqueCounter = counter;
...
2.PostJob
CamxResult ThreadManager::PostJob(
JobHandle hJob,
JobCb stoppedCb,
VOID** ppData,
BOOL isSplitable,
BOOL isBlocking)
{
CAMX_ASSERT(NULL != ppData);
CamxResult result = CamxResultSuccess;
result = m_pCore->AcceptNewJob(hJob, stoppedCb, ppData, isSplitable, isBlocking);
return result;
}
m_pCore->AcceptNewJob是将一个Job或者任务插入一个Queue,有一个工作线程循环从Queue中取Job任务执行,执行任务就是回调任务中的callback函数,AcceptNewJob实现
3.AcceptNewJob
camx-common/utils/src/camxthreadcore.cpp
CamxResult ThreadCore::AcceptNewJob(
JobHandle hJob,
JobCb stoppedCb,
VOID** ppData,
BOOL isSplitable,
BOOL isBlocking)
{
...
result = AddToPriorityQueue(pRuntimeJob);
...
}
调用AddToPriorityQueue将任务添加到queue任务队列,那么什么时候从这个queue中取任务执行呢?ThreadCore::WorkerThreadBody
4.ThreadCore::DoWork
VOID* ThreadCore::WorkerThreadBody(
VOID* pArg)
{
ThreadConfig* pWorker = NULL;
pWorker = reinterpret_cast<ThreadConfig*>(pArg);
CAMX_ASSERT(NULL != pWorker);
ThreadCore* pThreadCore = reinterpret_cast<ThreadCore*>(pWorker->pContext);
pThreadCore->DoWork();
return NULL;
}
VOID* ThreadCore::DoWork()
{
...
ProcessJobQueue(...);
...
}
CamxResult ThreadCore::ProcessJobQueue()
{
CamxResult result = CamxResultSuccess;
JobStatus status = JobStatus::Submitted;
UINT32 i = 0;
RuntimeJob* pJob = NULL;
JobQueue* pQueue = NULL;
CAMX_ASSERT(m_pThreadLock != NULL);
for (i = 0; i < MaxNumQueues; i++)
{
pQueue = &m_jobQueues[i];
do
{
status = pQueue->CheckAndDequeue(&pJob, m_pJobregistry);
if (NULL != pJob)
{
if (JobStatus::Ready == status)
{
DispatchJob(pJob);
}
else if (JobStatus::Stopped == status)
{
OnJobStopped(pJob);
}
if (pJob->isBlocking)
{
// Unblock caller, if it was blocking
pJob->pJobSemaphore->Signal();
}
m_pJobList->ReleaseJobEntry(pJob);
}
} while (NULL != pJob);
}
return result;
}
有个线程循环执行DoWork,最终调用checkAndDequeue取任务执行