Android Sync Framework

来源:互联网 发布:sql server怎么下载 编辑:程序博客网 时间:2024/06/09 22:52
定义“Synchronization between consumers and producers who are from different hardware components to use a buffer atomically” 应用背景在复杂的DMA管线如图形管线(多媒体,摄像头,GPU以及显示设备),一个buffer的消费者需要知道生产者什么时候完成生产(即创建一个Buffer,并往里面放置消费者所需要的数据)。同样地,生产者也需要知道消费者什么时候使用它创建的Buffer,以便它可以重新使用这个Buffer。而且,一个Buffer可能被多个不同的消费者使用不同的时间。另外,一个消费者可能需要互斥地消费多个Buffer,等等,有一个问题应运而生,就是如何保证多个消费者之间同步使用Buffer,以及生产者与消费者协调使用Buffer。因为Buffer是一个共享资源,且任何消费者或生产者对Buffer的使用都是排他性的(因为它们属于不同的硬件单元或模块),大体看来,需要解决如下两个问题:1. 消费者与生产者之间对Buffer的同步访问。2. 消费者之间对Buffer的同步访问。方案提出在Android中,引入了Sync框架,它添加了一组API,可以允许生产者和消费者之间以一种通用的方式解决上面提到的同步访问问题,平台需要实现这些Driver定义的同步原语以支持这个Sync框架。android Sync框架的目标是:1. 提供一个通用的API用于表达同步依赖关系。2. 允许驱动在不同的硬件模块中实现同步。3. 提供了一套用户空间的API,使得Compositor(等硬件模块)可以管理这些依赖。4. 提供丰富的测量数据,可以调试图形管线变慢和停止的问题。 驱动代码位于drivers/staging/android/sync.c,主要定义了如下三个数据类型:• sync_timelinesync_timeline是一种抽象的单调递增的计数器。通常情况下,每个驱动或硬件模块上下文只有一个sync_timeline。一般需要提供硬件模块特有的Sync驱动或使用通用的sw_sync实现,它是基于CPU的一种实现方式。实现上,是通过这些底层的驱动来创建sync_timeline的。一个硬件模块如果要提供Sync支持,则必须实现创建sync_timeline逻辑的驱动。• sync_ptsync_pt是一个抽象的值,标记在sync_timeline上。sync_pt只能属于唯一的sync_timeline。它有三种状态:活跃,信号和错误。开始时,处于活跃状态,当sync_timeline的计数值超过了sync_pt的值,就会触发状态转换为信号状态或错误状态。• sync_fencesync_fence是驱动间协调同步使用Buffer的主要原语。它包含一系列的sync_pt,这些sync_pt可能来自于不同的sync_timeline。另外,sync_fence上的sync_pt一旦确定,是不可更改的。可以同步或异步等待sync_fence对象状态的改变。两个sync_fence对象也可以合并生成第三个Fence对象,它包含了合并前的两个sync_fence对象的所有sync_pt的拷贝。sync_fence与文件描述符关联,用户空间可以通过它来协调显示管线等硬件单元之间的依赖性关系,即访问Buffer的先后顺序。 Ownership of a fence fdIf you get a fence fd from the framework, you must close it(Sf dup fence fd and transfer the new one) If you pass a fence fd to the framework, we will close it(If you want to keep using it, you must dup it, Sf merge fence if need transfer it)如何使用   一个实现Sync支持的驱动,应该拥有如下一个工作提交函数:1. 接受一个sync_fence参数,指定什么时候开始工作。2. 当sync_fence处于信号态后,异步地将对应的工作放入队列中去运行。3. 返回一个sync_fence对象,包含工作何时结束的信息。4. 当工作结束后,会将关联的sync_fence对象变成信号态。 接口声明实例:Driver API without fence support/** assumes buf is ready to be displayed.* blocks until the buffer is on screen.*/void display_buffer(struct dma_buf *buf); Driver API with fence support/** will display buf when fence is signaled.* returns immediately with a fence that will signal* when buf  is no longer displayed.*/struct sync_fence* display_buffer(struct dma_buf *buf, struct sync_fence *fence);  Android  Sync框架的软件Stack如下图所示:Android使用类Fence封装了sync用户接口,所以Android框架层中一般通用Fence类来使用Android Sync框架 Sync驱动Sync驱动包含两部分:• fence的通用操作,已经实现•各个sync 驱动相关的代码,由各个硬件Vendor实现,其中,基于CPU的sync驱动已经提供主要数据结构struct sync_timeline_opssync对象需要实现的一些操作struct sync_timeline代表一个sync对象的描述它包含许多struct sync_ptstruct sync_pt同步点有三种状态signaled(status > 0)active(status = 0)error(status < 0)它位于一个sync_timeline以及sync_fence中struct sync_fencestruct sync_fence_waiter在一个fence上异步等待的waiter的相关信息主要APIAPI focomponentsr sync_time implementerssync_timeline_create()  创建一个sync对象sync_timeline_destory()销毁一个sync对象sync_timeline_signal()signal a status change on a sync_timelinesync_pt_create()创建一个同步点sync_pt_free()释放一个同步点此函数仅能在该同步点未加入到一个fence前调用sync_fence_create()创建一个sync fenceAPI for sync_fence consumerssync_fence_merge()合并两个fence当两个sync_pt位于同一个timeline时,需要将他们合并成一个sync_pt, 并以触发时间最晚些的那个sync_pt那个为准sync_fence_fdget()根据一个fd获取对应的fence对象sync_fence_put()减少一次对sync fence的引用sync_fence_install()安装fence到一个文件描述符中sync_fence_waiter_init()sync_fence_wait_async()注册和异步等待某个fence对象sync_fence_cancel_async()取消一个异步等待sync_fence_wait()等待一个fence状态变为signaled 或error主要有三种IOCTL命令SYNC_IOC_WAITSYNC_IOC_MERGESYNC_IOC_FENCE_INFOfill_driver_data实现一个Sync-aware的驱动1.定义自己的timeline, pt数据结构如Mali 驱动定义的:[cpp] view plain copy 01.struct mali_sync_timeline  02.{  03.    struct sync_timeline timeline;  04.    atomic_t counter;  05.    atomic_t signalled;  06.};  07.struct mali_sync_pt  08.{  09.    struct sync_pt pt;  10.    u32 order;  11.    s32 error;  12.};  sw sync定义的:[cpp] view plain copy 01.struct sw_sync_timeline {  02.    struct    sync_timeline    obj;  03.    u32            value;  04.};  05.struct sw_sync_pt {  06.    struct sync_pt        pt;  07.    u32            value;  08.};  2.提供创建struct sync_timeline, struct sync_pt的接口, 3.实现struct sync_timeline_ops定义的一些回调函数如sw_sync驱动实现了如下函数,它是创建sync_timeline所必需的:[cpp] view plain copy 01.static struct sync_timeline_ops sw_sync_timeline_ops = {  02.    .driver_name = "sw_sync",  03.    .dup = sw_sync_pt_dup,  04.    .has_signaled = sw_sync_pt_has_signaled,  05.    .compare = sw_sync_pt_compare,  06.    .fill_driver_data = sw_sync_fill_driver_data,  07.    .timeline_value_str = sw_sync_timeline_value_str,  08.    .pt_value_str = sw_sync_pt_value_str,  09.};  4.提供创建fence的接口根据自身的设计,可能会提供如下两个IOCTL命令,注意区分上面提供的几个通用的IOCTL命令,以提供用户空间创建Fence的接口:创建Fence的命令:如sw_sync中定义义了如下命令:SW_SYNC_IOC_CREATE_FENCE另外,sw_sync还有一个改变sync_timeline当前值的命令(每个驱动也都会提供类似的操作,根据自身的逻辑,实现方法不尽相同):SW_SYNC_IOC_INC, 每当这个值变化时,会检查当前的值与位于sync_timeline中的syn_pt的值是否相等,以此来判断状态是否变为信号态。

原创粉丝点击