Camera HAL ThreadManager概述

ThreadManager概述

一、概述

Camera HAL 中存在 两套独立的 ThreadManager 实现,分别服务于不同的框架层:

特性 CamX ThreadManager CHI ThreadManager
适用层 CamX 核心框架 CHI Feature2 框架
最大线程数 15 16
最大注册作业 512 256
最大运行时作业 4096 -
同步作业 不支持 支持(Sync Thread)
顺序添加 不支持 支持(addInOrder)
作业分割 支持(isSplitable) 不支持
序列化执行 支持(isSerialize) 不支持

二、CamX ThreadManager 架构

2.1 组件层次图

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                        ThreadManager                            │
│                     (对外 API 门面)                              │
├─────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐  │
│  │ JobRegistry  │  │   JobList    │  │     ThreadCore      │  │
│  │ 作业注册表    │  │  运行时作业池 │  │    线程核心引擎     │  │
│  └──────────────┘  └──────────────┘  └──────────────────────┘  │
│                                              │                   │
│                                    ┌─────────┐                  │
│                                    │JobQueue │                  │
│                                    │优先级队列│                  │
│                                    └─────────┘                  │
└─────────────────────────────────────────────────────────────────┘

2.2 核心数据结构

JobHandle 编码格式
复制代码
┌─────────────────────────────────────┬─────────────────────────────┐
│     高 32 位: uniqueCounter         │     低 32 位: slot         │
│         (唯一标识计数器)             │      (注册表槽位索引)       │
└─────────────────────────────────────┴─────────────────────────────┘
RegisteredJob(已注册作业族)
cpp 复制代码
struct RegisteredJob {
    JobFunc     funcAddr;           // 作业函数地址
    CHAR        name[128];          // 作业名称
    JobCb       flushDoneCb;        // Flush 完成回调
    JobPriority priority;           // 优先级 (Critical/High/Normal)
    BOOL        isSerial;          // 是否序列化执行
    UINT32      uniqueCounter;     // 唯一计数器
    UINT32      slot;              // 注册表槽位
    UINT32      jobCount;          // 挂起作业数
    UINT32      inflightCount;     // 正在执行数
    UINT32      holdCount;         // 等待中的作业数
    UINT32      submittedCount;    // 已提交待执行数
    FlushStatus flushStatus;       // Flush 状态
    RuntimeJob* pFirstJob;          // 链表头
    RuntimeJob* pLastJob;           // 链表尾
    UINT32      cameraId;          // 相机 ID
};
RuntimeJob(运行时作业)
cpp 复制代码
struct RuntimeJob {
    UINT64      hJob;                      // 作业族句柄
    CHAR        name[256];                 // 作业名称
    JobCb       stoppedCb;                 // 停止回调
    VOID*       pData[MaxDataPartition];   // 数据分区数组
    BOOL        isSplitable;               // 是否可分割
    BOOL        isBlocking;                // 是否阻塞执行
    UINT32      numPartitions;             // 数据分区数
    JobStatus   status;                    // 作业状态
    UINT32      slot;                      // JobList 槽位索引
    Semaphore*  pJobSemaphore;             // 阻塞信号量
    RuntimeJob* pNext;                     // 下一个串行作业
};
作业状态机
复制代码
                 ┌───────────────────────────────────────────────┐
                 │                                               │
    ┌─────────┐  │  ┌─────────┐  ┌─────────┐  ┌─────────┐      │
    │Submitted│──┼─>│  Ready  │──>│On Hold  │──>│Stopped  │      │
    └─────────┘  │  └─────────┘  └─────────┘  └─────────┘      │
        入队      │  可执行       等待前置作业    Flush 停止       │
                 │                                               │
                 └───────────────────────────────────────────────┘

2.3 各组件职责

JobRegistry(作业注册表)
  • 职责 :
    • 管理所有已注册的作业族
    • 提供注册/注销接口
    • 维护作业计数统计(jobCount/inflightCount/holdCount/submittedCount)
    • 实现 Handle 编解码
cpp 复制代码
class JobRegistry {
    RegisteredJob   m_registeredJobs[512];    // 作业族数组
    BOOL            m_registeredSlots[512];   // 槽位占用标记
    UINT32          m_counter;               // 唯一计数器
    Mutex*          m_pRegistryLock;         // 注册表锁
    Mutex*          m_pFlushJobSubmitLock;    // Flush 与提交的同步锁
};
JobList(运行时作业池)
  • 职责 :
    • 提供 RuntimeJob 对象的分配/回收
    • 使用空闲链表管理可用槽位
    • 避免频繁的内存分配/释放
cpp 复制代码
class JobList {
    RuntimeJob  m_jobList[4096];           // 运行时作业数组
    JobSlot     m_freeList[4096];          // 空闲链表
    UINT32      m_freeHead;                // 链表头
    UINT32      m_freeTail;                // 链表尾
    UINT32      m_jobOccupancy;            // 当前占用数
};
ThreadCore(线程核心)
  • 职责 :
    • 创建/销毁工作线程
    • 管理优先级队列
    • 分发作业执行
    • 处理 Flush/Sync 操作
    • 集成健康监控
cpp 复制代码
class ThreadCore {
    JobQueue    m_jobQueues[3];            // Critical/High/Normal 三个优先级队列
    ThreadConfig m_workers[15];            // 工作线程配置
    Condition*  m_pReadOK;                 // 线程唤醒条件变量
    volatile BOOL m_stopped;               // 停止标志
    volatile BOOL m_jobPending;            // 新作业标志
};
JobQueue(优先级队列)
  • 职责 :
    • 实现作业入队/出队
    • 支持条件出队
    • 队列加锁保护

2.4 核心流程

创建流程
复制代码
ThreadManager::Create()
    └─ new ThreadManager()
    └─ Initialize()
        ├─ new JobRegistry() -> Initialize()
        ├─ new JobList() -> Initialize()
        └─ new ThreadCore() -> Initialize()
            └─ StartThreads()
                └─ 创建 numThreads 个工作线程
注册作业族流程
复制代码
ThreadManager::RegisterJobFamily()
    └─ JobRegistry::RegisterNewJob()
        ├─ 检查是否已注册
        ├─ 查找空闲槽位
        ├─ 填充 RegisteredJob 结构
        └─ 生成 JobHandle (counter << 32 | slot)
提交作业流程
复制代码
ThreadManager::PostJob(hJob, stoppedCb, ppData, isSplitable, isBlocking)
    └─ ThreadCore::AcceptNewJob()
        ├─ JobList::AcquireJobEntry() // 分配 RuntimeJob
        ├─ 处理作业分割(isSplitable)
        ├─ JobQueue::Enqueue()        // 加入优先级队列
        └─ Trigger()                  // 唤醒工作线程
            └─ m_pReadOK->Broadcast()
工作线程执行流程
复制代码
ThreadCore::WorkerThreadBody()
    └─ DoWork(threadIndex)
        while (!m_stopped) {
            // 等待新作业
            m_pReadOK->Wait()
            
            // ProcessJobQueue
            ProcessJobQueue(threadIndex)
                ├─ 从高优先级队列开始取作业
                ├─ JobQueue::CheckAndDequeue()
                │   ├─ 检查 Flush 状态
                │   ├─ 检查 Serial 依赖
                │   └─ 返回符合条件的作业
                ├─ 健康监控处理
                └─ DispatchJob(pJob)
                    └─ func(pData) // 执行作业函数
        }
Flush/Sync 流程
复制代码
ThreadManager::FlushJobFamily(hJob, pUserData, isBlocking)
    └─ ThreadCore::SyncOrFlushJob(hJob, pUserData, isBlocking, FlushRequested)
        ├─ JobRegistry::StartSyncOrFlush()
        │   ├─ 设置 flushStatus = FlushRequested
        │   └─ 设置 blockFlush = TRUE
        ├─ 唤醒所有工作线程处理剩余作业
        ├─ JobRegistry::WaitForSyncOrFlush()
        │   └─ pFlushSemaphore->Wait()
        └─ JobRegistry::CheckAllFlushDone()
            ├─ 检查 inflight count == 0
            ├─ 调用 flushDoneCb
            └─ Signal() 释放等待者

2.5 CamX 特有特性

作业分割(Job Splitting)
cpp 复制代码
// PostJob 时可以指定 isSplitable = TRUE
// 系统会将 ppData 数组中的每个分区作为独立子作业执行
// 所有子作业完成后视为整个作业完成

m_pCore->AcceptNewJob(hJob, stoppedCb, ppData, 
    TRUE,  // isSplitable
    isBlocking, maxExecTime, pJobName);
序列化执行(Serialization)
cpp 复制代码
// 注册时指定 isSerialize = TRUE
// 同一家族的作业必须串行执行
// JobQueue::CheckAndDequeue 会检查:
//   - 如果上一个作业仍在执行,则当前作业进入 OnHold 状态
//   - 只有前驱作业完成后,后继作业才能进入 Ready 状态
阻塞调用(Blocking)
cpp 复制代码
// PostJob 时指定 isBlocking = TRUE
// 调用方会阻塞等待作业完成

// ThreadCore 会为该作业创建 Semaphore
pJob->pJobSemaphore = Semaphore::Create();
// 作业执行完成后 Signal
pJob->pJobSemaphore->Signal();
// 调用方 Wait
pJob->pJobSemaphore->Wait();

三、CHI ThreadManager 架构

3.1 组件结构

CHI ThreadManager 没有 将组件拆分为独立的类,而是将所有逻辑集成在 CHIThreadManager 类中。

cpp 复制代码
class CHIThreadManager : public IMonitorClient {
    ChiRegisteredJob  m_registeredJobs[256];    // 已注册作业数组
    ChiThreadConfig    m_workers[16];           // 工作线程配置数组
    std::deque<ChiRuntimeJob*> m_pq;            // 全局异步作业队列
    std::array<..., 50> m_inflightJobs;         // HMS 监控的进行中作业
};

3.2 核心数据结构

ChiRuntimeJob(运行时作业)
cpp 复制代码
struct ChiRuntimeJob {
    UINT64         hJob;            // 作业句柄
    VOID*          pData;           // 作业数据
    UINT64         sequenceNum;     // 序列号
    ChiJobStatus   status;          // Submitted/Stopped/Invalid
    BOOL           isSync;          // 是否同步作业
    ChiJobPriority priority;        // Default/Critical
    UINT32         threadId;        // 执行线程 ID(Sync 作业)
    UINT64         execStartTime;   // 执行开始时间
    UINT64         maxExecTime;     // 最大执行时间
    pid_t          pid;             // 进程 ID
    pid_t          tid;             // 线程 ID
};
ChiRegisteredJob(已注册作业族)
cpp 复制代码
struct ChiRegisteredJob {
    JobFunc                  funcAddr;         // 作业函数地址
    CHAR                     name[255];        // 作业名称
    BOOL                     isSync;           // 是否同步作业
    BOOL                     isUsed;           // 槽位是否占用
    UINT64                   hRegister;        // 注册句柄
    volatile UINT32          inFlight;         // 进行中作业数
    volatile UINT32          jobPending;      // 队列中是否有作业
    JobFlushStatus           flushStatus;      // Flush 状态
    Condition*               pSyncJobCondn;    // Sync 线程条件变量
    Condition*               pFlushOK;        // Flush 完成条件
    Condition*               pSyncOK;         // Sync 完成条件
    Mutex*                   pQueueLock;       // 主队列锁
    Mutex*                   pHelperPQLock;    // 辅助队列锁
    BOOL                     addInOrder;       // 是否按序添加
    UINT64                   sequenceCounter;  // 序列号计数器
    UINT32                   cameraId;         // 相机 ID
    ChiThreadConfig          worker;           // Sync 线程配置
    std::deque<ChiRuntimeJob*> pq;             // 主作业队列
    std::deque<ChiRuntimeJob*> helperPQ;       // 辅助作业队列(乱序时使用)
};
ChiThreadConfig(线程配置)
cpp 复制代码
struct ChiThreadConfig {
    UINT32                   threadId;        // 逻辑线程号
    OSThreadHandle           hWorkThread;     // 系统线程句柄
    JobFunc                  workThreadFunc;  // 线程入口函数
    VOID*                    pContext;        // 上下文指针
    Mutex*                   pQueueLock;      // 队列锁
    ChiThreadStatus          status;          // 线程状态
    BOOL                     isUsed;          // 是否被 Sync 作业占用
    Condition*               pJobCondn;       // 唤醒条件变量
    JobHandle                hJob;            // 关联的作业句柄
    std::deque<ChiRuntimeJob*>* pq;          // 关联的作业队列
};

3.3 CHI 特有特性

同步作业(Sync Job)
cpp 复制代码
// 注册时指定 isSync = TRUE
// 系统会为该作业族创建独立的线程

CHIThreadManager::CreateSyncThread(rRegJob)
    ├─ 创建专用 Condition (pSyncJobCondn)
    ├─ 配置 ChiThreadConfig
    └─ ThreadCreate() 创建独立线程

// 同步作业线程独立于线程池,专门处理该作业族
顺序添加(addInOrder)
cpp 复制代码
// 注册时指定 addInOrder = TRUE
// 作业必须按 sequenceNum 递增执行
// 乱序到达的作业会暂存到 helperPQ

CHIThreadManager::AddToHelperQueue(pJob)
    ├─ 如果 sequenceNum <= sequenceCounter + 1
    │   └─ 直接加入主队列
    └─ 否则
        └─ 加入 helperPQ 并排序

CHIThreadManager::PostJob(hJob, pData, sequenceNum)
    ├─ AddToHelperQueue(pRuntimeJob)
    └─ 如果 helperPQ 头部可接受
        └─ 移入主队列并触发执行
双队列模型
复制代码
┌─────────────────────────────────────────────────────┐
│                 CHIThreadManager                     │
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │            异步线程池 (m_workers)           │    │
│  │                                              │    │
│  │   m_pAsyncCondn ──> 唤醒所有异步线程        │    │
│  │                                              │    │
│  │   ┌────────────────────────────────────┐    │    │
│  │   │  全局异步队列 (m_pq)              │    │    │
│  │   │  ┌───┐ ┌───┐ ┌───┐              │    │    │
│  │   │  │Job│ │Job│ │Job│ ...          │    │    │
│  │   │  └───┘ └───┘ └───┘              │    │    │
│  │   └────────────────────────────────────┘    │    │
│  └─────────────────────────────────────────────┘    │
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │     Sync 线程(每个 Sync 作业族独立)       │    │
│  │                                              │    │
│  │   pSyncJobCondn ──> 唤醒指定 Sync 线程     │    │
│  │                                              │    │
│  │   ┌────────────────────────────────────┐    │    │
│  │   │  每个作业族独立队列 (regJob.pq)    │    │    │
│  │   │  ┌───┐ ┌───┐ ┌───┐              │    │    │
│  │   │  │Job│ │Job│ │Job│ ...          │    │    │
│  │   │  └───┘ └───┘ └───┘              │    │    │
│  │   └────────────────────────────────────┘    │    │
│  └─────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────┘

3.4 CHI 核心流程

创建与启动
复制代码
CHIThreadManager::Create(ppInstance, pName, numThreads)
    └─ new CHIThreadManager(numThreads)
    └─ Initialize(pName)
        ├─ 创建 Mutex/Condition 同步原语
        └─ StartThreads()
            └─ 创建 numThreads 个异步工作线程
注册流程
复制代码
CHIThreadManager::RegisterJobFamily(jobFunc, name, phJob, isSync, addInOrder)
    ├─ 加锁 m_pRegisteredJobLock
    ├─ 检查是否已注册
    ├─ 查找空闲槽位
    ├─ 初始化 ChiRegisteredJob
    │   ├─ 创建 Condition/Mutex
    │   ├─ 设置 isSync / addInOrder
    │   └─ 生成 hRegister (Handle)
    ├─ 如果 isSync == TRUE
    │   └─ CreateSyncThread() // 创建专属线程
    └─ 设置 flushStatus = Noflush
工作线程执行
复制代码
CHIThreadManager::DoWork(pConfig)
    while (status != Stopped) {
        while (status != Stopped && 
               (isUsed && !jobPending || !isUsed && !m_jobPending)) {
            pJobCondn->Wait();  // 等待新作业
        }
        
        // ProcessJobQueue
        ProcessJobQueue(pConfig)
            ├─ 遍历 pq 中的作业
            ├─ 检查 flushStatus
            │   ├─ FlushRequested -> 弹出作业并释放
            │   └─ Noflush/SyncRequested -> DispatchJob
            ├─ MonitorAndDispatchJob (如果启用 HMS)
            │   ├─ 记录执行时间
            │   ├─ 加入 inflight 集合
            │   ├─ func(pData)
            │   └─ 从 inflight 集合移除
            └─ DispatchJob (无 HMS)
                └─ func(pData)
    }
Sync/Flush 流程
复制代码
CHIThreadManager::Sync(hJob, timeout)
    └─ SynchronizeBody(hJob, SyncRequested, timeout)
        ├─ 加锁
        ├─ 如果 addInOrder,处理 helperPQ
        ├─ 检查是否有进行中的作业
        ├─ 设置 flushStatus = SyncRequested/FlushRequested
        ├─ 触发所有相关线程处理剩余作业
        │   ├─ AsyncTrigger(TRUE) // 广播所有异步线程
        │   └─ SyncTrigger(rRegJob) // 唤醒 Sync 线程
        ├─ 等待所有作业完成
        │   └─ pFlushOK->TimedWait(timeout)
        └─ 重置 flushStatus = Noflush

四、两套实现对比

4.1 架构差异

维度 CamX ThreadManager CHI ThreadManager
设计模式 组件化(Registry/List/Core/Queue 分离) 单体式(所有逻辑在一个类中)
队列模型 3个优先级队列 + 链表 全局队列 + 每作业族独立队列
线程模型 纯线程池(无专属线程) 线程池 + Sync 专属线程
作业调度 优先级 + 序列号 FIFO + 可选顺序
序列化 支持(isSerialize) 不支持
作业分割 支持(isSplitable) 不支持

4.2 适用场景

CamX ThreadManager 适用于:

  • 需要作业并行执行的场景(如图像处理)
  • 需要优先级调度的场景
  • 需要序列化保证的场景
  • 需要作业分割的场景

CHI ThreadManager 适用于:

  • 需要同步作业族独立线程的场景
  • 需要严格顺序执行的场景
  • Feature2 层的算法处理

4.3 API 映射

功能 CamX CHI
创建 Create(ppInstance, name, numThreads) Create(ppInstance, name, numThreads=50)
注册 RegisterJobFamily(func, name, flushCb, priority, isSerialize, phJob, cameraId) RegisterJobFamily(func, name, phJob, isSync, addInOrder, cameraId)
提交 PostJob(hJob, stopCb, ppData, isSplitable, isBlocking, maxTime, name) PostJob(hJob, pData, seqNum, maxTime, priority)
注销 UnregisterJobFamily(hJob) UnregisterJobFamily(hJob)
Flush FlushJobFamily(hJob, userData, blocking) FlushJob(hJob) (内部调用)
Sync SyncJobFamily(hJob) Sync(hJob, timeout)
恢复 ResumeJobFamily(hJob) ResumeJobFamily(hJob) (需实现)

五、关键设计总结

5.1 线程安全

  • 所有共享数据访问都有 Mutex 保护
  • 状态标志使用原子操作
  • Condition 变量用于线程间通知

5.2 健康监控集成

  • 两套实现都继承 IMonitorClient
  • 支持作业超时检测
  • 支持暂停/恢复监控
  • 通过 OnScanAllJobs 上报失败作业

5.3 性能优化

  • 对象池模式(JobList 预分配 RuntimeJob)
  • 条件变量通知(避免忙等待)
  • 优先级队列(重要作业优先执行)
  • 批量唤醒(Broadcast vs Signal)

5.4 容错设计

  • Flush/Sync 超时机制
  • 作业停止回调
  • 状态机保护(非法状态转换检查)
  • 资源泄漏保护(析构函数中清理所有资源)
相关推荐
淡淡的香烟2 小时前
Android中的MQTT通信原理解析
android·物联网
淡淡的香烟2 小时前
Android Camera开发详解
android·音视频
mmsx3 小时前
基于 Android 的校园信息管理系统源码
android·java·okhttp
YF02114 小时前
如何进入Android工程模式
android
Kevin Coding5 小时前
JsonConvert:适用于 Android、鸿蒙与 Flutter 的 JSON 转 Model 插件
android·flutter·harmonyos
xcLeigh7 小时前
Go入门:基本数据类型全览与选择指南
android·服务器·golang·教程·go热门
alexhilton7 小时前
规范驱动开发:让AI生成符合预期的KMP代码
android·kotlin·android jetpack
码农coding7 小时前
android12 ActivityManagerService开机启动分析
android