zephyr上实现Android Fence机制
本文提出了一种跨核/跨线程的Fence同步机制设计方案。通过分析现有同步机制(如rbuf、DSP Mailbox)和Android Fence特性,设计了包含Timeline管理、Fence创建与合并、状态查询等核心功能的数据结构。方案支持硬件/软件Fence、AND/OR合并操作,采用共享内存实现跨核同步,并包含引用计数和错误处理机制。关键API包括Timeline创建与推进、Fence创建与合
·

跨核/跨线程 Fence 详细设计方案
一、项目中类似的实现分析
zephyr中已有以下跨核同步机制:
-
rbuf 机制 (
zephyr/lib/rbuf/)- 使用
INTER_RAM共享内存 - 通过 ring buffer 进行跨核消息传递
- 支持 CPU、DSP、BT、SC 四个核心
- 使用
-
DSP Mailbox 机制 (
zephyr/drivers/dsp/dsp_mailbox.c)- 使用共享 mailbox + 状态标志位
- 轮询等待 ACK(
wait_ack_timeout) - 使用中断触发(
mcu_trigger_irq_to_dsp)
-
BT HCI 同步 (
framework/bluetooth/bt_stack/)- 使用
k_sem进行同步等待 - 同核场景,使用信号量即可
- 使用
Android Fence 的核心特性
Android 的 SyncFence 包含:
- Timeline 机制:每个 fence 有序列号,基于 timeline
- 合并操作:支持 AND/OR 合并,形成树状结构
- 硬件 fence:支持 GPU/DMA 等硬件完成信号
- 引用计数:自动管理生命周期
- 状态查询:非阻塞查询状态
- 错误处理:支持错误状态传播
二、完整数据结构设计
// ========== Timeline定义 ==========
typedef struct fence_timeline {
uint32_t id; // Timeline ID(如GPU、DMA等)
atomic_t seq; // 当前序列号(单调递增)
uint32_t core_id; // 所属核心
sys_slist_t fence_list; // 关联的fence列表
os_mutex mutex; // 保护timeline
} fence_timeline_t;
// ========== Fence状态 ==========
typedef enum {
FENCE_STATE_PENDING = 0, // 等待中
FENCE_STATE_SIGNALED = 1, // 已信号
FENCE_STATE_ERROR = 0xFFFFFFFF // 错误状态
} fence_state_t;
// ========== Fence类型 ==========
typedef enum {
FENCE_TYPE_SOFTWARE = 0, // 软件fence
FENCE_TYPE_GPU, // GPU硬件fence
FENCE_TYPE_DMA, // DMA硬件fence
FENCE_TYPE_MERGED // 合并fence
} fence_type_t;
// ========== 共享内存中的Fence结构 ==========
typedef struct fence_shared {
// 基础信息
atomic_t state; // 状态(PENDING/SIGNALED/ERROR)
atomic_t ref_count; // 引用计数(跨核可见)
uint32_t magic; // 魔数:0xFENCE1234
uint32_t creator_core; // 创建者核心ID
// Timeline信息
uint32_t timeline_id; // Timeline ID
uint32_t seq; // 序列号(在timeline上的位置)
// 类型和标志
uint32_t type; // Fence类型
uint32_t flags; // 标志位
// 合并fence信息(如果是合并fence)
uint32_t merge_type; // MERGE_AND(0) / MERGE_OR(1)
uint32_t merge_count; // 合并的fence数量
uint32_t merge_fences[4]; // 合并的fence句柄(最多4个,可扩展)
// 等待者信息
atomic_t waiters_count; // 等待者计数
uint32_t reserved[2]; // 保留字段,保证对齐
} fence_shared_t;
// ========== 本地Fence句柄 ==========
typedef struct fence {
fence_shared_t *shared; // 指向共享内存
uint32_t local_core_id; // 本地核心ID
// 本地同步原语
os_sem local_sem; // 本地信号量(同核使用)
// Timeline关联
fence_timeline_t *timeline; // 关联的timeline
// 合并fence的子fence列表(本地)
sys_slist_t merged_fences; // 如果是合并fence,存储子fence
// 引用计数(本地)
atomic_t local_ref_count; // 本地引用计数
// 回调函数(用于硬件fence)
void (*signal_callback)(struct fence *fence, void *data);
void *signal_data;
// 链表节点(用于timeline管理)
sys_snode_t timeline_node;
sys_snode_t global_node;
} fence_t;
// ========== 合并操作类型 ==========
typedef enum {
FENCE_MERGE_AND = 0, // AND操作:所有fence都信号才信号
FENCE_MERGE_OR = 1 // OR操作:任一fence信号就信号
} fence_merge_type_t;
三、核心 API 设计
3.1 Timeline 管理
/**
* @brief 创建timeline
* @param timeline_id Timeline ID(如GPU、DMA等)
* @param core_id 所属核心
* @return timeline句柄
*/
fence_timeline_t* fence_timeline_create(uint32_t timeline_id, uint32_t core_id);
/**
* @brief 获取timeline的当前序列号
*/
uint32_t fence_timeline_get_seq(fence_timeline_t *timeline);
/**
* @brief Timeline前进(硬件完成时调用)
* @param timeline Timeline句柄
* @param seq 完成的序列号
*/
int fence_timeline_advance(fence_timeline_t *timeline, uint32_t seq);
3.2 Fence 创建
/**
* @brief 创建fence(基于timeline)
* @param timeline Timeline句柄
* @param seq 序列号(如果为0,自动分配)
* @return fence句柄
*/
fence_t* fence_create(fence_timeline_t *timeline, uint32_t seq);
/**
* @brief 创建硬件fence(GPU/DMA)
* @param timeline Timeline句柄
* @param signal_callback 信号回调(硬件完成时调用)
* @param signal_data 回调数据
*/
fence_t* fence_create_hardware(fence_timeline_t *timeline,
void (*signal_callback)(fence_t*, void*),
void *signal_data);
/**
* @brief 增加fence引用计数
*/
fence_t* fence_ref(fence_t *fence);
/**
* @brief 减少fence引用计数(引用为0时自动销毁)
*/
void fence_unref(fence_t *fence);
3.3 Fence 合并(核心特性)
/**
* @brief 合并多个fence(类似Android Fence::merge)
* @param fences fence数组
* @param count fence数量
* @param merge_type AND或OR
* @return 合并后的fence
*/
fence_t* fence_merge(fence_t **fences, uint32_t count, fence_merge_type_t merge_type);
/**
* @brief 合并两个fence(常用接口)
*/
fence_t* fence_merge_two(fence_t *fence1, fence_t *fence2, fence_merge_type_t merge_type);
3.4 Fence 等待
/**
* @brief 等待fence信号
* @param fence fence句柄
* @param timeout_ms 超时时间(-1表示永久等待)
* @return 0成功,-ETIMEDOUT超时,-EIO错误
*/
int fence_wait(fence_t *fence, int32_t timeout_ms);
/**
* @brief 非阻塞查询fence状态
* @return FENCE_STATE_PENDING/SIGNALED/ERROR
*/
fence_state_t fence_get_state(fence_t *fence);
/**
* @brief 检查fence是否已信号(非阻塞)
*/
bool fence_is_signaled(fence_t *fence);
3.5 Fence 信号
/**
* @brief 信号fence(软件fence)
*/
int fence_signal(fence_t *fence);
/**
* @brief 信号错误状态
*/
int fence_signal_error(fence_t *fence);
/**
* @brief Timeline前进时自动信号fence(硬件fence)
* 当timeline的seq >= fence的seq时,自动信号fence
*/
void fence_timeline_advance_signal(fence_timeline_t *timeline, uint32_t seq);
四、关键实现细节
4.1 Timeline 机制实现
// Timeline管理
static sys_slist_t g_timeline_list;
static os_mutex g_timeline_list_lock;
fence_timeline_t* fence_timeline_create(uint32_t timeline_id, uint32_t core_id)
{
fence_timeline_t *timeline = mem_malloc(sizeof(fence_timeline_t));
if (!timeline) return NULL;
timeline->id = timeline_id;
timeline->core_id = core_id;
atomic_set(&timeline->seq, 0);
sys_slist_init(&timeline->fence_list);
os_mutex_init(&timeline->mutex);
os_mutex_lock(&g_timeline_list_lock, OS_FOREVER);
sys_slist_append(&g_timeline_list, &timeline->node);
os_mutex_unlock(&g_timeline_list_lock);
return timeline;
}
int fence_timeline_advance(fence_timeline_t *timeline, uint32_t seq)
{
fence_t *fence;
sys_snode_t *node;
os_mutex_lock(&timeline->mutex, OS_FOREVER);
// 更新序列号
uint32_t old_seq = atomic_get(&timeline->seq);
if (seq > old_seq) {
atomic_set(&timeline->seq, seq);
}
// 检查并信号所有seq <= 当前seq的fence
SYS_SLIST_FOR_EACH_NODE(&timeline->fence_list, node) {
fence = CONTAINER_OF(node, fence_t, timeline_node);
if (fence->shared->seq <= seq &&
atomic_get(&fence->shared->state) == FENCE_STATE_PENDING) {
// 自动信号fence
fence_signal_internal(fence);
}
}
os_mutex_unlock(&timeline->mutex);
return 0;
}
4.2 Fence 合并实现(核心)
fence_t* fence_merge(fence_t **fences, uint32_t count, fence_merge_type_t merge_type)
{
fence_t *merged_fence;
fence_shared_t *merged_shared;
uint32_t i;
if (count == 0 || count > 4) return NULL;
// 1. 创建合并fence
merged_fence = fence_create_internal(FENCE_TYPE_MERGED);
merged_shared = merged_fence->shared;
// 2. 设置合并信息
merged_shared->merge_type = merge_type;
merged_shared->merge_count = count;
// 3. 保存子fence的句柄(在共享内存中)
for (i = 0; i < count; i++) {
merged_shared->merge_fences[i] = fence_to_handle(fences[i]);
fence_ref(fences[i]); // 增加子fence引用
}
// 4. 检查是否所有子fence都已信号(AND)或任一已信号(OR)
bool should_signal = false;
if (merge_type == FENCE_MERGE_AND) {
// AND:检查是否所有都信号
should_signal = true;
for (i = 0; i < count; i++) {
if (!fence_is_signaled(fences[i])) {
should_signal = false;
break;
}
}
} else {
// OR:检查是否有任一信号
for (i = 0; i < count; i++) {
if (fence_is_signaled(fences[i])) {
should_signal = true;
break;
}
}
}
// 5. 如果应该立即信号,直接信号
if (should_signal) {
fence_signal(merged_fence);
} else {
// 6. 注册回调,监听子fence状态变化
for (i = 0; i < count; i++) {
fence_register_merge_callback(fences[i], merged_fence);
}
}
return merged_fence;
}
// 子fence信号时的回调
static void fence_merge_callback(fence_t *child_fence, void *data)
{
fence_t *merged_fence = (fence_t *)data;
fence_shared_t *merged_shared = merged_fence->shared;
uint32_t i;
bool should_signal = false;
if (merged_shared->merge_type == FENCE_MERGE_AND) {
// AND:检查所有子fence
should_signal = true;
for (i = 0; i < merged_shared->merge_count; i++) {
fence_t *child = handle_to_fence(merged_shared->merge_fences[i]);
if (child && !fence_is_signaled(child)) {
should_signal = false;
break;
}
}
} else {
// OR:任一信号即可
should_signal = true;
}
if (should_signal) {
fence_signal(merged_fence);
}
}
4.3 硬件 Fence 集成
// GPU完成中断处理
void gpu_complete_isr(uint32_t seq)
{
fence_timeline_t *gpu_timeline = fence_timeline_get(GPU_TIMELINE_ID);
if (gpu_timeline) {
// Timeline前进,自动信号所有seq <= seq的fence
fence_timeline_advance(gpu_timeline, seq);
}
}
// 创建GPU fence
fence_t* fence_create_gpu(uint32_t seq)
{
fence_timeline_t *gpu_timeline = fence_timeline_get(GPU_TIMELINE_ID);
if (!gpu_timeline) {
gpu_timeline = fence_timeline_create(GPU_TIMELINE_ID, CPU);
}
fence_t *fence = fence_create(gpu_timeline, seq);
fence->shared->type = FENCE_TYPE_GPU;
return fence;
}
4.4 跨核 Fence 等待(增强版)
int fence_wait_cross_core(fence_t *fence, int32_t timeout_ms)
{
fence_shared_t *shared = fence->shared;
uint32_t curr_core = fence_get_core_id();
// 1. 如果是合并fence,需要等待所有子fence
if (shared->type == FENCE_TYPE_MERGED) {
return fence_wait_merged(fence, timeout_ms);
}
// 2. 检查timeline(硬件fence)
if (shared->type == FENCE_TYPE_GPU || shared->type == FENCE_TYPE_DMA) {
fence_timeline_t *timeline = fence->timeline;
uint32_t current_seq = fence_timeline_get_seq(timeline);
// 如果timeline已经超过fence的seq,直接返回
if (current_seq >= shared->seq) {
return 0;
}
}
// 3. 常规等待逻辑(同之前设计)
// ...
}
int fence_wait_merged(fence_t *merged_fence, int32_t timeout_ms)
{
fence_shared_t *shared = merged_fence->shared;
uint32_t i;
int ret = 0;
if (shared->merge_type == FENCE_MERGE_AND) {
// AND:等待所有子fence
for (i = 0; i < shared->merge_count; i++) {
fence_t *child = handle_to_fence(shared->merge_fences[i]);
if (child) {
ret = fence_wait(child, timeout_ms);
if (ret != 0) break;
}
}
} else {
// OR:等待任一fence信号
// 可以使用k_poll或轮询所有fence
// ...
}
return ret;
}
五、使用示例
// ========== 示例1:GPU渲染fence ==========
void render_frame(void)
{
fence_timeline_t *gpu_timeline = fence_timeline_get(GPU_TIMELINE_ID);
// 创建GPU fence,序列号为当前timeline seq + 1
uint32_t render_seq = fence_timeline_get_seq(gpu_timeline) + 1;
fence_t *render_fence = fence_create_gpu(render_seq);
// 提交渲染任务(传递seq给GPU)
gpu_submit_render(render_seq);
// 等待渲染完成
fence_wait(render_fence, 1000);
fence_unref(render_fence);
}
// GPU完成中断中
void gpu_isr(void)
{
uint32_t completed_seq = gpu_get_completed_seq();
fence_timeline_advance(gpu_timeline, completed_seq);
// 自动信号所有seq <= completed_seq的fence
}
// ========== 示例2:合并多个fence ==========
void wait_multiple_operations(void)
{
fence_t *gpu_fence = fence_create_gpu(seq1);
fence_t *dma_fence = fence_create_dma(seq2);
fence_t *cpu_fence = fence_create_software();
// 合并:等待GPU和DMA都完成(AND操作)
fence_t *merged = fence_merge_two(gpu_fence, dma_fence, FENCE_MERGE_AND);
// 等待合并fence
fence_wait(merged, 5000);
// 清理
fence_unref(merged);
fence_unref(gpu_fence);
fence_unref(dma_fence);
fence_unref(cpu_fence);
}
// ========== 示例3:复杂合并 ==========
void complex_sync(void)
{
fence_t *f1 = fence_create_gpu(seq1);
fence_t *f2 = fence_create_dma(seq2);
fence_t *f3 = fence_create_software();
// 先合并f1和f2(AND)
fence_t *merged1 = fence_merge_two(f1, f2, FENCE_MERGE_AND);
// 再与f3合并(OR:f1&&f2完成 或 f3完成)
fence_t *fences[] = {merged1, f3};
fence_t *final = fence_merge(fences, 2, FENCE_MERGE_OR);
fence_wait(final, -1);
// 清理所有引用
fence_unref(final);
fence_unref(merged1);
fence_unref(f1);
fence_unref(f2);
fence_unref(f3);
}
六、与 Android Fence 的对比
| 特性 | Android Fence | 本设计 | 说明 |
|---|---|---|---|
| Timeline | ✅ | ✅ | 基于序列号的timeline |
| 合并操作 | ✅ | ✅ | 支持AND/OR合并 |
| 硬件fence | ✅ | ✅ | 支持GPU/DMA等 |
| 引用计数 | ✅ | ✅ | 自动管理生命周期 |
| 跨进程 | ✅ | ✅ | 在RTOS上是跨核 |
| 状态查询 | ✅ | ✅ | 非阻塞查询 |
| 错误处理 | ✅ | ✅ | 支持错误状态 |
| 文件描述符 | ✅ | ❌ | RTOS不需要,用句柄 |
七、关键点
- Timeline 机制:每个 fence 有序列号,硬件完成时自动信号
- 合并操作:支持 AND/OR,可形成树状结构
- 硬件集成:GPU/DMA 完成时自动信号相关 fence
- 引用计数:自动管理生命周期,避免内存泄漏
- 跨核支持:共享内存 + 中断,支持跨核同步
八、Fence 使用场景总结
一、图形渲染场景
-
GPU 渲染完成等待
- 等待 GPU 完成绘制后再显示
- 避免在渲染未完成时使用缓冲区
-
DMA2D 传输完成
- 等待 DMA2D 完成图像拷贝/转换
- 确保数据已写入目标缓冲区
-
多硬件并行渲染
- GPU 和 DMA2D 同时工作,等待两者都完成
- 使用合并 fence(AND 操作)
-
Surface 双缓冲同步
- 等待上一帧显示完成再开始新帧
- 等待 back buffer 释放再使用
- 避免缓冲区冲突
二、跨核通信场景
-
CPU 等待 DSP 处理完成
- CPU 提交音频/图像处理到 DSP
- 等待 DSP 完成后再使用结果
-
CPU 等待 BT CPU 完成
- CPU 发送 HCI 命令到 BT CPU
- 等待 BT CPU 处理完成
-
多核心流水线
- CPU 准备数据 → DSP 处理 → GPU 渲染 → Display 显示
- 每个阶段等待前一个阶段完成
三、硬件加速场景
-
音频编解码同步
- 等待 DSP 完成音频编码/解码
- 确保数据可用后再处理
-
视频解码同步
- 等待硬件解码器完成一帧解码
- 避免使用未完成的解码数据
-
图像处理同步
- 等待 JPEG 硬件解码完成
- 等待图像缩放/旋转完成
四、DMA 传输场景
-
SPI DMA 传输完成
- 等待 SPI DMA 完成数据传输
- 确保数据已写入/读出
-
MMC/SD 卡 DMA 传输
- 等待 SD 卡 DMA 读写完成
- 避免在传输中访问数据
-
音频 DMA 传输
- 等待音频 DMA 完成播放/录制
- 确保缓冲区可安全使用
五、显示同步场景
-
VSync 同步
- 等待垂直同步信号
- 在 VSync 时 swap buffer
-
多图层合成
- 等待所有图层渲染完成
- 使用合并 fence 等待所有图层
-
显示引擎同步
- 等待 Display Engine 完成一帧显示
- 避免 tearing
六、复杂同步场景
-
条件等待
- 等待 GPU 渲染完成或超时
- 任一条件满足即继续(OR 合并)
-
依赖链
- 任务 A 完成后启动任务 B
- 任务 B 完成后启动任务 C
- 形成依赖链
-
资源释放等待
- 等待多个资源都释放(AND 合并)
- 任一资源释放即可(OR 合并)
七、错误处理场景
-
超时检测
- 硬件操作超时后标记错误
- 通过 fence 错误状态通知上层
-
错误传播
- 硬件错误通过 fence 传播
- 合并 fence 中任一错误则整体失败
八、性能优化场景
-
异步渲染
- 不阻塞主线程,异步等待渲染完成
- 使用 fence 状态查询
-
批量操作
- 提交多个渲染任务,等待全部完成
- 使用合并 fence 提高效率
-
流水线并行
- 同时处理多帧数据
- 使用 timeline 管理多个 fence
更多推荐


所有评论(0)